Shallow Copy vs Deep Copy

There are two ways of copying one variable into another.

  • Shallow Copy
  • Deep Copy

Shallow Copy

When a reference variable(object) is copied into another variable using an equal(=) operator, a shallow copy of the original variable is created, which means that both the variables point towards the same memory location.

const org = {
   name: "Rohit",
   city: "Kolkata",
}

const copy = org;
console.log(org);
copy.city="Bangalore";
console.log(org)
console.log(copy)

image.png

From the above example, we can see that on changing the city key for the copy variable the city key for the original variable(org) also changes, this is because of shallow copying.

Different ways of copying.

  • The assignment operator.
  • The spread operator.
const org = {
   name: "Rohit",
   city: "Kolkata",
}

const copy = {...org}
console.log(org);
copy.city="Bangalore";
console.log(org)
console.log(copy)

image.png

But the spread operator is not the solution, since the spread operator only works when the object does not contain nested values.

const org = {
   name: "Rohit",
   location: {
   city: "Kolkata",
   },
}

const copy = {...org}
copy.location.city="Bangalore";
console.log(org)
console.log(copy)

image.png

Another way of shallow copying is using Object.assign().

const org = {
   name: "Rohit",
   location: {
   city: "Kolkata",
   },
}

const copy = Object.assign({}, org)
copy.location.city="Bangalore";
console.log(org)
console.log(copy)

image.png

Deep Copy

So as we observe, we need a way to deep copy the object. Deep copy is the method by which all the values of the original variable are copied and allocated to a separate location in the memory. In this way, both variables will be independent of each other.

We can deep copy using the following:

  • JSON methods :
const org = {
   name: "Rohit",
   location: {
   city: "Kolkata",
   },
}

const copy = JSON.parse(JSON.stringify(org))
copy.name="Prasad"
copy.location.city="Bangalore";
console.log(org)
console.log(copy)

image.png

Note - JSON methods are good to use when the object size is small and the values are serializable

  • Using recursion function - We can write our deep copy function using recursion.
function deepCopy(obj) {
   let output, val, key;
   output = Array.isArray(obj) ? [] : {};
   for (key in obj) {
       val = obj[key];
       output[key] = (typeof val === "object") ? deepCopy(val) : val;
   }
   return output;
}

const org = {
   name: "Rohit",
   location: {
   city: "Kolkata",
   },
}

const copy = deepCopy(org);

copy.name="Prasad"
copy.location.city="Bangalore"
console.log(org)
console.log(copy)

image.png

  • Lodash cloneDeep() - one of the most used ways of cloning an object is using the cloneDeep() method provided by the Lodash Library. Lodash cloneDeep() also recursively clones the object.
const _ = require('lodash');
const org = {
   name: "Rohit",
   location: {
   city: "Kolkata",
   },
}
const copy = _.cloneDeep(org);