Object.assign()

2016-12-28

I came across the JavaScript Object.assign() method recently, which is used to copy properties from one or more objects into a new or target object. Here’s how it’s used:

var objectA = {one: 1};
var objectB = {two: 2};
var objectC = Object.assign({}, objectA, objectB);
console.log(objectC); // {one: 1, two: 2};

The Object.assign() method can take any number of objects, but the first is the returned value. Above I merge everything into a new, empty object, instead of objectA or objectB to avoid mutating them. The right most object gets priority, merging itself into the object to the left, and so on.

Pretty neat! On the surface, this feels pretty useful. It can come in handy when assigning objects or other default properties. Here’s an example of that:

var defaults = {
  color: '#ffffff',
  private: true
};

var custom = {
  color: '#000000'
};

var options = Object.assign({}, defaults, custom);
console.log(options); // {color: '#000000', private: true}

The color value in the default object is overridden by the matching value in the custom object. All is good if you are using basic values in your objects.

Watch out for nested objects! One GOTCHA when using Object.assign() is to avoid making assumptions with nested objects and their values. Here’s a nested object carrying over as expected:

var defaults = {
  color: '#ffffff',
  position: { left: 0, top: 0 }
};

var custom = {
  color: '#000000',
  position: { left: 10 }
};

var options = Object.assign({}, defaults, custom);
console.log(options); // {color: '#000000', position: {left: 10}}

See how the position value only includes the left parameter? The method takes the whole value and overrides the original. Therefore it sees the parameter position is present, and replaces the default value with the new value, which happens to be an object with only the left parameter, but not top value.

console.log(options.position.top); // undefined

The top parameter is completely gone. No good! This is intended behavior, but if using Object.assign() willy nilly can leave you in a world of hurt. I recommend looking at deep-assign, a small node library that extends the method to deeply assign values. With the same values as above, here’s the final output:

console.log(options); // {color: '#000000', position: {left: 10, top: 0}}