5 Ways to Deep Copy Objects in JavaScript

In JavaScript, An object is always allocated in a single memory point, and whenever you assign the object to another variable, It’s just a reference to the same variable which results in weird behavior if we manipulate objects. To solve this problem, You can use 5 ways to deep copy JavaScript Objects.
Table of Contents
- What is Shallow Copy in JavaScript?
- What is Deep Copy in JavaScript?
- 5 Steps to Deep Copy Object
- Cheat Sheet for Copying objects in JS
What is Shallow Copy in JavaScript?
The Shallow copy is assigning an object to another variable with an equal sign which results in the new object pointing to the same memory reference. If we change the latter, it will affect the former object because both are pointing to the same memory location.
The below code clearly shows you that the a
variable which is assigned to b
variable gets affected once we change the property of b
variable
// Created an object
var a = { name: "John" }
// Assigned the object to another variable
var b = a;
// changing the "name" property of "b" variable
b.name = "Sam";
// logging b and a in console.
console.log(b); // { name: "Sam" }
console.log(a); // { name: "Sam" }
What is Deep Copy in JavaScript?
The Deep copy is assigning an object to another variable without any reference pointing to the former, It can be done using any of the following methods:
5 Ways to Deep Copy Object in JavaScript:
1. Copy Object using JavaScript Spread Operator
We can copy an object using JavaScript Spread Operator, which is a ...
syntax used to copy the top-level objects. It won’t copy nested objects.
// Created an object
var a = { name: "John" }
// Clone object using spread operator
var b = {...a};
// changing the "name" property of "b" variable
b.name = "Sam";
// logging b and a in console.
console.log(b); // { name: "Sam" }
console.log(a); // { name: "John" }
2. Copy Object using JavaScript Object.assign() method
The second way of copying an object is a good old traditional Object.assign() JavaScript method. It can be used for top-level object copy but is not fit for nested objects.
// Created an object
let a = { name: "John" }
// Clone object using object.assign method
let b = Object.assign(a);
// changing the "name" property of "b" variable
b.name = "Sam";
// logging b and a in console.
console.log(b); // { name: "Sam" }
console.log(a); // { name: "John" }
3. Copy Object using JSON.stringify() and JSON.parse()
The JSON.stringify
method is used to convert the javascript object into string whereas JSON.parse
is used to convert the stringified JSON/JavaScript object into an actual JavaScript Objects in memory. If we make use of these two javascript methods, we can easily copy nested javascript objects but we can’t copy functions.
If your object doesn’t contain any functions in it, then you can use JSON.parse(JSON.stringify(yourObject))
method of copying an object in JavaScript
// Created an object
let a = {
name: "John",
info: {
country: "USA"
}
}
// Clone nested objects using JSON.parse and JSON.stringify method
let b = JSON.parse(JSON.stringify(a));
// changing the "name" property of "b" variable
b.name = "Sam";
// Chaning the "country" property inside "info" property of "b" variable
b.info.country = "India"
// logging b and a in console.
console.log(b); // { name: "Sam", info: { country: "USA"} }
console.log(a); // { name: "John", info: { country: "India"} }
4. Copy Object using Lodash cloneDeep() method
Lodash is a utility library that contains many helper functions for arrays and objects. we can use _.cloneDeep()
method to copy nested objects.
The advantage of cloneDeep
method of copying an object over JSON.parse and JSON.stringify is it copies functions in the object as well.
// Created an object
let a = {
name: "John",
info: {
country: "USA"
}
}
// Clone nested objects using loadash clondDeep() method
let b = _.cloneDeep(a));
// changing the "name" property of "b" variable
b.name = "Sam";
// Chaning the "country" property inside "info" property of "b" variable
b.info.country = "India"
// logging b and a in console.
console.log(b); // { name: "Sam", info: { country: "USA"} }
console.log(a); // { name: "John", info: { country: "India"} }
5. Copy Objects using Our Own JavaScript Logic
To deep copy a nested object in JavaScript, we can create a property and loop over the main object and assign the key value pairs to the newly created object.
Inside the loop, If the type of the property is “object” then again we can recursively call the same function to loop over again. In this method, we can copy nested objects with functions as well. This is what happens under the hood of cloneDeep
method in lodash.
function cloneDeep(originalObj) {
let duplicateObj = {};
for(let key in originalObj) {
if(typeof originalObj[key] === 'object') {
duplicateObj[key] = this.makeDuplicateObj(originalObj[key]);
} else {
duplicateObj[key] = originalObj[key];
}
}
return duplicateObj;
}
The cloneDeep
function creates a local variable, the for loop checks whether the property of the original object contains any object, if the type is an object then the cloneDeep
invokes recursively.
As long as there’s a property that contains an object, this function calls recursively and assigns all the properties of the original object to the duplicateObj
without having any reference to it.
Conclusion
In this detailed tutorial, you learned 5 ways to copy objects and also you know when to use which method based on your need. Here’s a quick cheatsheet for copying objects.
Method | Pros | Cons |
Spread operator {...yourObject} | Simple syntax is recommended in most use-cases. Copies only top-level objects | doesn’t copy the nested objects. |
Object.assign(yourObject) method | Copies top-level objects including functions. | doesn’t copy the nested objects. |
JSON.stringify(JSON.parse(yourObject)) method | deep copies nested objects | Affects performance if it’s a large object. and doesn’t copy functions in the objects. |
Lodash _.cloneDeep(yourObject) method | The preferred way for nested object cloning in JavaScript including functions. | adds an external dependency to your project |
Recursive function | Can get control over the logic and can copy nested objects with functions as well | Takes time to write the logic. reinventing the wheel. Better to use lodash if there’s no business logic needed. |
If you find any new solutions to solve the deep copy problem in JS, feel free to add that in the comments section below.