This isn't necessarily exhaustive.
Spread syntax
options = {...optionsDefault, ...options};
Advantages:
If authoring code for execution in environments without native support, you may be able to just compile this syntax (as opposed to using a polyfill). (With Babel, for example.)
Less verbose.
Disadvantages:
When this answer was originally written, this was a proposal, not standardized. When using proposals consider what you'd do if you write code with it now and it doesn't get standardized or changes as it moves toward standardization. This has since been standardized in ES2018.
Literal, not dynamic.
Object.assign()
options = Object.assign({}, optionsDefault, options);
Advantages:
Standardized.
Dynamic. Example:
var sources = [{a: "A"}, {b: "B"}, {c: "C"}]; options = Object.assign.apply(Object, [{}].concat(sources)); // or options = Object.assign({}, ...sources);
Disadvantages:
- More verbose.
- If authoring code for execution in environments without native support you need to polyfill.
This is the commit that made me wonder.
That's not directly related to what you're asking. That code wasn't using Object.assign(), it was using user code (object-assign) that does the same thing. They appear to be compiling that code with Babel (and bundling it with Webpack), which is what I was talking about: the syntax you can just compile. They apparently preferred that to having to include object-assign as a dependency that would go into their build.
This isn't necessarily exhaustive.
Spread syntax
options = {...optionsDefault, ...options};
Advantages:
If authoring code for execution in environments without native support, you may be able to just compile this syntax (as opposed to using a polyfill). (With Babel, for example.)
Less verbose.
Disadvantages:
When this answer was originally written, this was a proposal, not standardized. When using proposals consider what you'd do if you write code with it now and it doesn't get standardized or changes as it moves toward standardization. This has since been standardized in ES2018.
Literal, not dynamic.
Object.assign()
options = Object.assign({}, optionsDefault, options);
Advantages:
Standardized.
Dynamic. Example:
var sources = [{a: "A"}, {b: "B"}, {c: "C"}]; options = Object.assign.apply(Object, [{}].concat(sources)); // or options = Object.assign({}, ...sources);
Disadvantages:
- More verbose.
- If authoring code for execution in environments without native support you need to polyfill.
This is the commit that made me wonder.
That's not directly related to what you're asking. That code wasn't using Object.assign(), it was using user code (object-assign) that does the same thing. They appear to be compiling that code with Babel (and bundling it with Webpack), which is what I was talking about: the syntax you can just compile. They apparently preferred that to having to include object-assign as a dependency that would go into their build.
For reference object rest/spread is finalised in ECMAScript 2018 as a stage 4. The proposal can be found here.
For the most part object assign and spread work the same way, the key difference is that spread defines properties, whilst Object.assign() sets them. This means Object.assign() triggers setters.
It's worth remembering that other than this, object rest/spread 1:1 maps to Object.assign() and acts differently to array (iterable) spread. For example, when spreading an array null values are spread. However using object spread null values are silently spread to nothing.
Array (Iterable) Spread Example
const x = [1, 2, null , 3];
const y = [...x, 4, 5];
const z = null;
console.log(y); // [1, 2, null, 3, 4, 5];
console.log([...z]); // TypeError
Object Spread Example
const x = null;
const y = {a: 1, b: 2};
const z = {...x, ...y};
console.log(z); //{a: 1, b: 2}
This is consistent with how Object.assign() would work, both silently exclude the null value with no error.
const x = null;
const y = {a: 1, b: 2};
const z = Object.assign({}, x, y);
console.log(z); //{a: 1, b: 2}
Spread Operator(Object inside Object)
Object.assign vs Object Spread in Node.js
I've actually been wondering lately how these two measure up. Very interesting.
I ran his same tests in Node and got similar results.
HOWEVER I ran the tests in Chrome and got very different results:
First set (Object.assign directly)
Object spread x 3,032,358 ops/sec ±0.78% (54 runs sampled) Object.assign() x 21,901,498 ops/sec ±5.47% (56 runs sampled) Fastest is Object.assign()
Second set (Object.assign to new {})
Object spread x 2,991,669 ops/sec ±0.93% (53 runs sampled) Object.assign() x 16,659,708 ops/sec ±1.50% (57 runs sampled) Fastest is Object.assign()
Object.assign is still way faster than spread in Chrome. Still not a huge deal unless you're trying to optimize, but worth considering.
More on reddit.comWhen would you use this function instead of Object.assign or the spread operator?
You wouldn't (unless you really needed to support IE and couldn't transpile with something like Babel). That site is just a little dated so you're not going to see any newer ES6+ syntax. From their homepage:
More on reddit.comAll functions work properly in IE 9 and above - most of them are compatible with IE 8. Common pitfalls are mentioned alongside concerned functions. Available plugins have no dependencies and are tested in IE 9+, some work properly in IE 8 and below.