Reputation: 11599
I have a sample JSBin code at http://jsbin.com/givolafala/edit?html,js,console,output
var oldObject = { name: 'John', address: { city: 'new york'}};
var newObject = Object.assign({}, oldObject);
console.log(oldObject);
console.log(newObject);
newObject.name = 'Mathew';
newObject.address.city = 'los angeles';
console.log(oldObject);
console.log(newObject);
In this example, I'm changing the name which is at the top level from John
to Mathew
. The Object.assign
returns the new state with the new name Mathew
. The oldObject
keeps its previous value John
.
If I change any value in any level other than the root, it does not work. In the example I change the city to los angeles
, and you will notice that the newObject
and the oldObject
have the same city los angeles
. So the oldObject
state is mutated.
Is this a bug?
Upvotes: 2
Views: 227
Reputation: 15696
This is not a bug, this is called reference. There's a difference between how primitive values and objects (references to objectes actually) behaves.
var oldObject = { name: 'John', address: { city: 'new york'}};
oldObject
consist of:
name
which is a string value (primitive)addres
which is an object, so oldObject
really has a reference to address
objectNow:
var newObject = Object.assign({}, oldObject);
After copying newObject
also has name
value and address
reference
newObject.name = 'Mathew';
Here you change a value of newObject
's property.
newObject.address.city = 'los angeles';
But here you change a property of an object that newObject
references. But this reference is also in oldObject
so this will change oldObject
too.
Basically both newObject
and oldObject
have a reference to same same address
object.
What you expected to achieve is called deep copy.
Upvotes: 5
Reputation: 74738
I guess the description of Object.assign()
says everything:
The Object.assign() method only copies enumerable and own properties from a source object to a target object.
It uses [[Get]] on the source and [[Set]] on the target, so it will invoke getters and setters.Therefore it assigns properties versus just copying or defining new properties. This may make it unsuitable for merging new properties into a prototype if the merge sources contain getters. For copying property definitions, including their enumerability, into prototypes Object.getOwnPropertyDescriptor() and Object.defineProperty() should be used instead.
Upvotes: 2