December 17, 2022

Tutorials

Deep Copying Objects in JavaScript

When working with objects in JavaScript, it’s important to understand the difference between a shallow copy and a deep copy. A shallow copy of an object only copies the top-level properties of the object, whereas a deep copy creates a completely independent copy of the object and all its nested objects, which is also known as object cloning.

We usually shallow copy objects using methods like spreading:

const obj = {
   name: 'john',
   age: '24'
}

const copyObj = {...obj};

This is okay for an object that has only one level and it’s not nested but if the object was nested this method would copy only the top level properties. so we have to use deep copying in that case.

Here are a few methods you can use to create a deep copy of an object in JavaScript:

Method 1: JSON.parse() and JSON.stringify()

One of the simplest ways to create a deep copy of an object is to use the JSON.stringify() and JSON.parse() methods. The JSON.stringify() method converts a JavaScript object to a JSON string, and the JSON.parse() method converts a JSON string to a JavaScript object.

Here’s an example of how to use these methods to create a deep copy of an object:

const originalObject = {
  name: 'John',
  address: {
    city: 'New York',
    state: 'NY'
  },
  hobbies: ['reading', 'cooking']
};

const deepCopy = JSON.parse(JSON.stringify(originalObject));

This method is quick and easy, but it does have a few limitations. For example, it won’t work for objects that contain functions or circular references. and it doesn’t copy Date objects properly.

Method 2: Recursion

Another way to create a deep copy of an object is to use recursion. This involves creating a new object and iterating over the properties of the original object, copying each property and its value to the new object. If the value is an object, you can use recursion to create a deep copy of that object as well.

Here’s an example of how to use recursion to create a deep copy of an object:

function deepCopy(obj) {
  let copy = {};

  for (let key in obj) {
    if (typeof obj[key] === 'object') {
      copy[key] = deepCopy(obj[key]);
    } else {
      copy[key] = obj[key];
    }
  }

  return copy;
}

const originalObject = {
  name: 'John',
  address: {
    city: 'New York',
    state: 'NY'
  },
  hobbies: ['reading', 'cooking']
};

const copy = deepCopy(originalObject);

This method is more versatile than the JSON.parse() and JSON.stringify() method, as it can handle objects with functions and circular references. However, it may be more time-consuming to implement, especially for large objects with many nested objects.

Method 3: lodash.cloneDeep()

If you’re using the lodash library, you can use the _.cloneDeep() method to create a deep copy of an object. This method uses recursion to create a deep copy of the object and all its nested objects.

(UPDATE) Method 4: structuredClone() global function

since the release of this post a new interesting and very useful method has been introduced, the global structredClone function makes it easy to deep copy objects and other values in JavaScript, this method uses the structured clone algorithm and it’s more efficient and more straightforward to use than recursion and it is supported by the latest versions of chrome and firefox. here is an example:

const mushrooms1 = {
  amanita: ["muscaria", "virosa"],
};

const mushrooms2 = structuredClone(mushrooms1);

In conclusion, there are a few different methods you can use to create a deep copy of an object in JavaScript. However if you have properties in the object that can’t be converted to json, recursion is the best method.