ECMAScript 6: merging objects via Object.assign()
New version of this blog post: inside “ECMAScript 6: new OOP features besides classes”.
For merging objects, ECMAScript 6 will have the function
This function modifies target and returns it: it first copies all enumerable [1] own operties of source_1 to target, then those of source_2, etc.
In ECMAScript 6, property keys can be either strings or symbols. The latter are a new kind of unique identifier; there are never any name clashes with symbols as keys. Object.assign() supports both strings and symbols as keys.
Properties in the target object are created via assignment (internal operation [[Put]]). That means that if target has (own or inherited) setters [1], those will be invoked during copying. An alternative would have been to define new properties [2], an operation which always creates new own properties and never invokes setters. There originally was a proposal for a variant of Object.assign() that uses definition instead of assignment. That proposal has been rejected for ECMAScript 6 (but may be reconsidered for later editions).
The task of a constructor is to set up instance properties. Alas, variable names are always mentioned redundantly for this task:
My favorite would have been the following syntax to completely remove that redundancy (CoffeeScript and TypeScript both have ways of doing this, but I prefer this syntax):
Object.assign() at least enables you to avoid some of the redundancy:
In ECMAScript 6, { x, y } is an abbreviation for { x: x, y: y }.
ECMAScript 5, you use a function expression to add a method to an object:
ECMAScript 6 has a more concise syntax for methods [3]. Thanks to Object.assign(), you don’t have to abandon that syntax:
You can also use Object.assign() to (shallowly) clone an object:
If you are only interested in an object’s own properties, things become simpler:
Copying all properties of one object to another one is a common operation in JavaScript. This blog post explains ECMAScript 6’s implementation of it, which is called Object.assign().
This merging operation has a name in the JavaScript ecosystem that is only used there (and, unfortunately, clashes with classic OOP terminology): “extend”. Two examples of “extend” being provided by libraries:
- Prototype: Object.extend(destination, source)
Prototype first used the name “extend” for this operation.
- Underscore.js: _.extend(destination, *sources)
Object.assign()
For merging objects, ECMAScript 6 will have the function
Object.assign(target, source_1, ..., source_n)
This function modifies target and returns it: it first copies all enumerable [1] own operties of source_1 to target, then those of source_2, etc.
Property keys: either strings or symbols
In ECMAScript 6, property keys can be either strings or symbols. The latter are a new kind of unique identifier; there are never any name clashes with symbols as keys. Object.assign() supports both strings and symbols as keys.
Copying versus assignment
Properties in the target object are created via assignment (internal operation [[Put]]). That means that if target has (own or inherited) setters [1], those will be invoked during copying. An alternative would have been to define new properties [2], an operation which always creates new own properties and never invokes setters. There originally was a proposal for a variant of Object.assign() that uses definition instead of assignment. That proposal has been rejected for ECMAScript 6 (but may be reconsidered for later editions).
Use cases for Object.assign()
Setting up instance properties
The task of a constructor is to set up instance properties. Alas, variable names are always mentioned redundantly for this task:
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
My favorite would have been the following syntax to completely remove that redundancy (CoffeeScript and TypeScript both have ways of doing this, but I prefer this syntax):
class Point {
constructor(this.x, this.y) {
}
}
Object.assign() at least enables you to avoid some of the redundancy:
class Point {
constructor(x, y) {
Object.assign(this, { x, y });
}
}
In ECMAScript 6, { x, y } is an abbreviation for { x: x, y: y }.
Adding a method to an object
ECMAScript 5, you use a function expression to add a method to an object:
MyClass.prototype.foo = function (arg1, arg2) {
...
};
ECMAScript 6 has a more concise syntax for methods [3]. Thanks to Object.assign(), you don’t have to abandon that syntax:
Object.assign(MyClass.prototype, {
foo(arg1, arg2) {
...
}
});
Cloning an object
You can also use Object.assign() to (shallowly) clone an object:
var copy = Object.assign({ __proto__: obj.__proto__ }, obj);
If you are only interested in an object’s own properties, things become simpler:
var copy = Object.assign({}, obj);
References
- Object properties in JavaScript
- Properties in JavaScript: definition versus assignment
- Callable entities in ECMAScript 6
Comments
Post a Comment