Deep Cloning and Shallow Cloning in Javascript - Veltris

Deep Cloning and Shallow Cloning in Javascript

September 21, 2020 | Akkamra

    Cloning or copying is a process of generating an identical copy of an object. It is used almost in every javascript project and is highly recommended to use.

    There are three ways to clone an object:

    1. Use the spread (…) syntax.
    2. Use the Object.assign() method
    3. Use the JSON.stringify() and JSON.parse() methods

    The question here is that why can’t we just use “=” to copy objects. The answer is that objects in javascript have references values and can’t be just simply copied with the use of “=”. Let’s see with an example:

    const actors1 = { harry: 1, hermione: 2, ron: 3 };
    //using "=" operator to copy 
    const actors2 = actors1;
    console.log("actors1 :", actors1, "actors2 :", actors2);
    //Output :
    //actors1 : { harry: 1, hermione: 2, ron: 3 } actors2: { harry: 1, hermione: 2, ron: 3 }

    We can simply copy the values, but there is a pitfall to this approach, and we can see that if we edit any of the two objects.

    const actors1 = { harry: 1, hermione: 2, ron: 3 };
    //using "=" operator to copy 
    const actors2 = actors1;
    console.log("actors1 :", actors1, "actors2 :", actors2);
    //Output :
    //actors1 : { harry: 1, hermione: 2, ron: 3 } actors2: { harry: 1, hermione: 2, ron: 3 }
    actors2.snape = 4;
    console.log("actors1 :", actors1, "actors2 :", actors2);
    //Output :
    //actors1 : { harry: 1, hermione: 2, ron: 3, snape: 4 } actors2: { harry: 4, hermione: 2, ron: 3, snape: 4 }

    This happened because actors2 stored the pointer to the value in the memory and not the actual values. That’s why both get affected.

    Now, the three ways to create a clone.

    Using the spread {…} operator

    The spread operator is used to expand an iterable object into the list of arguments. It is used for copying, concatenating, adding a new item to the list and combining objects, etc.

    We will see the use of spread operating into cloning an object in the following code

    const actors1 = { harry: 1, hermione: 2, ron: 3 };
    const cloneActors = { ...actors1 };
    console.log("cloneActors: ", cloneActors);
    //Output:
    //cloneActors: { harry: 1, hermione: 2, ron: 3 }

    Now, this will create a clone to actors1. This will create a shallow copy of the object.

    Using the Object.assign() method

    The assign() method is used to copy one or more source objects to a target object. Let’s see with an example:

    const actors1 = { harry: 1, hermione: 2, ron: 3 };
    const cloneActors = Object.assign({}, actors1);
    console.log("cloneActors: ", cloneActors);
    //Output:
    //cloneActors: { harry: 1, hermione: 2, ron: 3 }

    This will also create a shallow copy of the object.

    Using JSON.stringify and JSON.parse method

    JSON.parse() method parse the data, and it becomes a javascript object.

    JSON.stringify method converts javascript object or value to a JSON string.

    The cloning of the object using JSON methods will give us a deep copy. Let us see with an example.

    const actors1 = { harry: 1, hermione: 2, ron: 3 };
    const cloneActors = JSON.parse(JSON.stringify(actors1));
    console.log(cloneActors);
    //Output:
    //cloneActors: { harry: 1, hermione: 2, ron: 3 }

    Difference between deep clone and shallow clone

    A shallow copy is created when we use the spread operator. The spread operator will not work with multidimensional arrays or nested arrays.

    A shallow copy means only the first level is copied, and the other standards are referenced. Let’s see with an example.

    const actors1 = { harry: 1, hermione: 2, ron: 3 };
    const cloneActors = JSON.parse(JSON.stringify(actors1));
    console.log(cloneActors);
    //Output:
    //cloneActors: { harry: 1, hermione: 2, ron: 3 }
    const nestedObj = {
       movie: 'Breaking Bad',
       characters: {
          leadCharacter: 'Walter White'
       }
    };
    //Shallow Copy
    const nestedObjClone = { ...nestedObj };
    //change clone object and nested object
    nestedObjClone.movie = 'Money Heist';
    nestedObjClone.characters.leadCharacter = 'Professer';
    console.log(nestedObj, "nestedObj")
    //{movie:'Breaking Bad', {chara}}
    //{characters: {leadCharacter: "Professer"}
    //movie: "Breaking Bad"}
    console.log("nestedObjClone", nestedObjClone);
    //{characters: {leadCharacter: "Professer"}
    //movie: "Money Heist"}

    Related Articles