Search code examples
javascriptobjectmethods

I don't understand these lines of code from Object.assign() MDN documentation



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


Solution

  • 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?