DEV Community

Keertivaas S
Keertivaas S

Posted on

Creating a deep copy of a JS Object

Using Lodash :

const _ = require('lodash');

const originalObject = {
prop1: "value1",
prop2: {
nestedProp: "value2"
}
};

const deepCopy = _.cloneDeep(originalObject);

Using Underscore js :

const _ = require('underscore');
const deepclone = require('underscore.deepclone');

_.mixin(deepclone); // Add deepClone function to Underscore

const originalObject = {
prop1: "value1",
prop2: {
nestedProp: "value2"
}
};

However, using packages like lodash and underscore can be heavy as

const deepCopy = _.deepClone(originalObject);

A combination of JSON.parse and JSON.stringify :

const originalObject = {
prop1: "value1",
prop2: {
nestedProp: "value2"
}
};

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

When to use JSON.parse(JSON.stringify(obj)) :

  • Simple Data Transfer: If you're dealing with basic objects containing only primitive values (strings, numbers, booleans) and need to transfer them between environments that understand JSON, this method can be a quick and straightforward solution.
  • Shallow Copy with Specific Data Loss: If you intentionally want to remove functions, Dates, or other complex data types during the copy process, this method can achieve that. However, be aware of the potential data loss.

Issues with JSON.parse(JSON.stringify(obj)) :

  • Data Loss: This method can lose data during the conversion process. Functions, Dates, and other complex data types might not be accurately represented in JSON format and could be lost during parsing back to an object.
  • Circular References: It can't handle circular references (objects referencing themselves) in the data. This can lead to infinite loops during parsing.
  • Performance: While seemingly simple, stringifying and parsing a large object can be less performant compared to dedicated deep copy functions.

Advantages of using lodash clonedeep or underscore package based solution :

  • Preserves Data: These methods are designed to handle various data types and maintain their integrity during the copy process.
  • Handles Circular References: They can effectively deal with circular references in the object structure, preventing infinite loops.
  • Optimized for Deep Copying: Deep copy libraries like Lodash are often optimized for performance when creating deep copies of complex objects.

Conclusion :

In most cases, for reliable deep copying of objects in JavaScript applications, Lodash's _.cloneDeep or similar methods from other libraries like Underscore (with extensions) are preferred choices. They offer better performance, handle complex data types and circular references, and provide a more robust solution for deep copying objects.

Edit :

Adding another method of cloning - structuredClone, which is a built in function in Javascript : Credits : @jonrandy

const originalObject = {
prop1: "value1",
prop2: {
nestedProp: "value2"
}
};

originalObject.itself = originalObject;

const deepCopy = structuredClone(originalObject);

The above way preserves circular references as well as does not require external packages to download!

Top comments (2)

Collapse
 
jonrandy profile image
Jon Randy 🎖️

Or use the JS built-in function structuredClone.

Collapse
 
justanordinaryperson profile image
Keertivaas S

Adding as an edit, with credits :)