The limits of Object.assign()

So, you have been using Object.assign to create copies of your objects right? Here’s a warning for you. Object.assign does not perform a deep copy.

Consider the following example:

var paul = {
  age: 30,
  height: 180,
  address: {
    city: 'Toronto',
    street: 'Markham'
  }
};

Let’s say we want to create a second object for “John” who has the same age, and lives in the same city, but has a different height and lives in a different street.

var john = Object.assign({}, paul);
john.height = 175;
john.address.street = 'Mercer';

We should have two independent objects right? Let’s see…

console.log(paul);

// Outputs:
// {
//    age: 30,
//    height: 180,
//    address: {
//      city: 'Toronto',
//      street: 'Mercer'
//    }
// }

console.log(john);

// Outputs:
// {
//    age: 30,
//    height: 175,
//    address: {
//      city: 'Toronto',
//      street: 'Mercer'
//    }
// }

The street property also changed for paul, what happened? For primitive properties like age and height, Object.assign copied its values, but for non-primitive properties like address it copied the reference.

You’ve been warned.

Update

There’s a better way to do this. Object.assign() accepts multiple arguments so we can “merge” multiple objects at the same time.

var john = Object.assign({}, paul, {height: 175, address: {street: 'Mercer'}});

The last arguments takes precedence over the first ones so we end up with our desired final object:

console.log(john);

// Outputs:
// {
//    age: 30,
//    height: 175,
//    address: {
//      city: 'Toronto',
//      street: 'Mercer'
//    }
// }

But the good thing is that now, our object paul remains untouched.

console.log(paul)

// Outputs:
// {
//    age: 30,
//    height: 180,
//    address: {
//      city: 'Toronto',
//      street: 'Markham'
//    }
// }

That’s how you create a copy of an object.

So, what do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.