const obj1 = { a: 0, b: { c: 0 } };
const obj2 = Object.assign({}, obj1);
console.log(obj2); // { a: 0, b: { c: 0 } }
obj1.a = 1;
console.log(obj1); // { a: 1, b: { c: 0 } }
console.log(obj2); // { a: 0, b: { c: 0 } }
obj2.a = 2;
console.log(obj1); // { a: 1, b: { c: 0 } }
console.log(obj2); // { a: 2, b: { c: 0 } }
obj2.b.c = 3;
console.log(obj1); // { a: 1, b: { c: 3 } }
console.log(obj2); // { a: 2, b: { c: 3 } }
I was reading in the MDN documentation about Object.assign() method , then some lines of code stopped me (specifically starting from obj2.b.c = 3) . I don't understand how changing the c value in obj2 affected obj1 . Even though the values of the two (a) properties changed individually in each object before, and none of the two values affected the other . What do I not understand about the nested Object (b) ?
I would be thankful for any answers or references for articles that explains the problem and the solution deeply
As you may read in Object.assign page:
For deep cloning, we need to use alternatives, because Object.assign() copies property values.
If the source value is a reference to an object, it only copies the reference value.
For more, read about Deep copy and Shallow copy.
In your example:
const obj1 = { a: 0, b: { c: 0 } };
const obj2 = Object.assign({}, obj1);
obj2
has a shallow copy of obj1
, which means it has a copy of the values that are in the first level (a
) and a reference to the object that's in b
.
If you change obj2.a
, you would change the value in the copy.
But when you do obj2.b
you are using the reference of the object in obj1
that had {c: 0}
.
That's why when you change obj2.b
you are referring to that same object (c
) which was referred in obj1
. They both point to the same memory address.
If you want to do a deep copy you can use JSON.parse(JSON.stringify(OBJ))
which basically will create a string from your object, then it passes it to JSON.stringif
which will return a new object (with new references).
You may also have a look at: What is the most efficient way to deep clone an object in JavaScript?