5 Ways to Deep Copy Objects in JavaScript

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

  1. What is Shallow Copy in JavaScript?
  2. What is Deep Copy in JavaScript?
  3. 5 Steps to Deep Copy Object
    1. Copy Object using JavaScript Spread Operator.
    2. Copy Object using JavaScript Object.assign() method.
    3. Deep Copy Object using JavaScript JSON.parse() and JSON.stringify() method
    4. Deep Copy Object using Lodash cloneDeep method.
    5. Deep Copy Object using our own JavaScript Logic.
  4. 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.

MethodPros Cons
Spread operator {...yourObject}Simple syntax is recommended in most use-cases. Copies only top-level objectsdoesn’t copy the nested objects.
Object.assign(yourObject) methodCopies top-level objects including functions.doesn’t copy the nested objects.
JSON.stringify(JSON.parse(yourObject)) methoddeep copies nested objectsAffects performance if it’s a large object. and doesn’t copy functions in the objects.
Lodash _.cloneDeep(yourObject) methodThe preferred way for nested object cloning in JavaScript including functions.adds an external dependency to your project
Recursive functionCan get control over the logic and can copy nested objects with functions as wellTakes 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.