DEV Community

Avnish
Avnish

Posted on

What is the most efficient way to deep clone an object in JavaScript

Efficient Ways to Deep Clone an Object in JavaScript

Cloning an object in JavaScript requires creating a duplicate where changes to the clone don't affect the original. Deep cloning involves copying all properties, including nested objects. Below are the most efficient methods to achieve deep cloning, with their pros and cons.


1. Using JSON.parse() and JSON.stringify()

This method converts an object into a JSON string and then parses it back into a new object.

Example:

const obj1 = { name: "John", age: 30, address: { city: "New York" } };
const obj2 = JSON.parse(JSON.stringify(obj1));

obj2.address.city = "Los Angeles";
console.log(obj1.address.city); // Output: "New York"
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • Simple and concise.
  • Works well for objects with primitive and nested values.

Limitations:

  • Doesn't support:
    • Functions.
    • undefined values.
    • Symbols.
    • Circular references.
  • Converts special objects (e.g., Date, Set, Map) into plain objects.

2. Using structuredClone()

The structuredClone() method is a native JavaScript API that deeply clones objects, supporting more data types than JSON.parse() and JSON.stringify().

Example:

const obj1 = { name: "Alice", age: 25, date: new Date() };
const obj2 = structuredClone(obj1);

obj2.date.setFullYear(2025);
console.log(obj1.date.getFullYear()); // Original date remains unchanged
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • Supports complex types like Date, Set, Map, and TypedArray.
  • Handles circular references gracefully.

Limitations:

  • Requires a modern browser or Node.js (v17+).
  • Slightly less efficient than JSON.parse() for simple objects.

3. Using Lodash’s cloneDeep()

Lodash is a utility library that offers a reliable cloneDeep() function for deep cloning.

Example:

const _ = require("lodash");

const obj1 = { name: "Mark", hobbies: ["reading", "traveling"] };
const obj2 = _.cloneDeep(obj1);

obj2.hobbies.push("coding");
console.log(obj1.hobbies); // Output: ["reading", "traveling"]
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • Handles all data types, including circular references.
  • Reliable for production-grade applications.

Limitations:

  • Requires installing Lodash (npm install lodash).
  • Adds a dependency to your project.

4. Using Recursive Functions

For small, custom use cases, you can write your own deep cloning function.

Example:

const deepClone = (obj) => {
  if (obj === null || typeof obj !== "object") return obj;

  if (Array.isArray(obj)) return obj.map(deepClone);

  const clonedObj = {};
  for (const key in obj) {
    clonedObj[key] = deepClone(obj[key]);
  }
  return clonedObj;
};

const obj1 = { name: "Emma", address: { city: "London", zip: 12345 } };
const obj2 = deepClone(obj1);

obj2.address.city = "Paris";
console.log(obj1.address.city); // Output: "London"
Enter fullscreen mode Exit fullscreen mode

Advantages:

  • Full control over the cloning process.
  • No external library required.

Limitations:

  • More verbose and error-prone.
  • Needs enhancements to handle special objects like Date, Set, Map.

5. Using Spread Syntax or Object.assign() (Shallow Cloning)

These methods create a shallow copy, duplicating only the top-level properties. For deep cloning, this approach doesn't suffice.

Example:

const obj1 = { name: "Liam", address: { city: "Berlin" } };
const obj2 = { ...obj1 };

obj2.address.city = "Munich";
console.log(obj1.address.city); // Output: "Munich" (Not a deep clone)
Enter fullscreen mode Exit fullscreen mode

Comparison of Methods

Method Supports Circular Refs Supports Special Types Performance Use Case
JSON.parse/JSON.stringify No No High Simple objects, non-circular refs.
structuredClone() Yes Yes Moderate Complex objects, modern environments.
Lodash.cloneDeep() Yes Yes Moderate Production applications.
Custom Recursive Optional No Varies Custom lightweight solutions.
Spread / Object.assign No No High Shallow cloning only.

Conclusion

  • Use structuredClone() if you need a built-in solution for modern environments.
  • Use JSON.parse() and JSON.stringify() for simple and performance-critical scenarios.
  • Use Lodash's cloneDeep() for reliable, production-grade deep cloning.
  • Write a custom function for unique, lightweight use cases.

Top comments (0)