Shallow Copy and deep copy | Javascript Interview Series
Introduction
In JavaScript, whenever we assign one object to another, by default, it only copies the reference (i.e., memory location), not the data.
Problem Statement
We want to copy an object, but the original object should not change its value when the copy is updated:
JavaScript
let obj1 = { name: "Jhon" };
let user = obj1;
user.name = "doe";
console.log(obj1); // { name: "doe" }
console.log(user); // { name: "doe" }
In the above code, obj1 and user are pointing to the same memory location. This is called object copy by reference. To fix this, we have two ways.
Shallow Copy
1st Way (using Object.assign)
JavaScript
let obj = { name: "Jhon" };
let user = Object.assign({}, obj);
user.name = "deo";
console.log("obj.. ", obj); // { name: "Jhon" }
console.log("user.. ", user); // { name: "deo" }
2nd Way (using Destructuring)
JavaScript
let obj = { name: "Jhon" };
let user = { ...obj, job: "SDE" };
user.name = "deo";
console.log("obj.. ", obj); // { name: "Jhon" }
console.log("user.. ", user); // { name: "deo", job: "SDE" }
Limitations of Shallow Copy
It only copies data to the first level. If we create an object inside another object, it won't be able to copy that nested structure.
JavaScript
const objRaj = {
name: "raj",
place: "delhi",
study: {
ssc: "fbs",
college: "IIT",
},
};
let objRajesh = Object.assign({}, objRaj);
objRajesh.place = "Mumbai"; // Working
objRajesh.study.college = "NIT"; // Not working (modifies original too)
console.log("raj.. ", objRaj); // { name: "raj", place: "delhi", study: { college: "NIT" } }
console.log("rajehs.. ", objRajesh);
Deep Copy
To fix the nested copy issue, we use Deep Copy. We can perform this by converting the object to a JSON string and parsing it back:
JavaScript
// JSON.stringify - converts JavaScript obj to JSON text
// JSON.parse - converts JSON back to a JavaScript object
const objRaj = {
name: "raj",
place: "delhi",
study: {
ssc: "fbs",
college: "IIT",
},
};
let objRajesh = JSON.parse(JSON.stringify(objRaj));
objRajesh.place = "Mumbai";
objRajesh.study.college = "NIT";
console.log("raj.. ", objRaj);
console.log("rajesh.. ", objRajesh);
Limitations of Deep Copy
๐ก It is not able to copy functions and times present inside the object.
JavaScript
const objRaj = {
name: "raj",
study: { college: "IIT" },
showData: function () {
console.log("display", this.name);
},
};
let objRajesh = JSON.parse(JSON.stringify(objRaj));
// objRajesh.showData will be undefined here
Using Lodash
What is Lodash?
๐ก Lodash is a utility library provided by JavaScript which holds a lot of helper functions.
You can use the _.cloneDeep() function to resolve deep copy issues, including functions.
JavaScript
// Using lodash
let objRajesh = _.cloneDeep(objRaj);
objRajesh.name = "Rajesh";
objRajesh.study.college = "NIT";
console.log("raj.. ", objRaj);
console.log("rajesh.. ", objRajesh);
Using Prototype Inheritance (__proto__)
JavaScript
const obj1 = {
name: "himanshu",
city: "ranchi",
getData: function () {
console.log(this.name + " from " + this.city);
},
};
const obj2 = {
name: "shekhar",
getData: function () {
console.log(this.name + " from " + this.city);
},
};
obj2.__proto__ = obj1;
obj2.city = "bengaluru";
console.log(obj1.city); // "ranchi"
console.log(obj2.city); // "bengaluru"