JavaScript objects and arrays are reference types, meaning that when we assign a variable to an object or array, the variable holds a reference to the original object or array. This can be problematic when we want to copy an object or array without altering the original. That’s where deep clone comes in.
Deep cloning is the process of creating a new instance of an object or array with the same values as the original, but with a new memory address. This means that any changes made to the cloned object or array will not affect the original.
There are several ways to deep clone an object in JavaScript, and we will discuss some of the most popular methods here.
Using JSON.stringify() and JSON.parse()
One way to deep clone an object or array is to use JSON.stringify() and JSON.parse(). This method works by first converting the object or array to a JSON string using JSON.stringify(), and then parsing the string back into an object or array using JSON.parse().
const originalObject = {
prop1: "Hello",
prop2: {
nestedProp1: "World",
nestedProp2: [1, 2, 3],
},
};
const clonedObject = JSON.parse(JSON.stringify(originalObject));
clonedObject.prop2.nestedProp1 = "Universe";
console.log(originalObject.prop2.nestedProp1); // Output: "World"
In this example, we use JSON.stringify() to convert originalObject
to a JSON string and then use JSON.parse() to parse the string back into an object. This creates a deep clone of originalObject
, which we can modify without affecting the original object.
Using the Lodash Library
Lodash is a popular JavaScript library that provides many utility functions, including a function for deep cloning objects. Here’s an example:
const _ = require('lodash');
const originalObject = { foo: 'bar', baz: { qux: 'quux' } };
const clonedObject = _.cloneDeep(originalObject);
This creates a new object, clonedObject, that is a deep copy of originalObject.
Using a Recursive Function
Another way to deep clone an object or array is to use a recursive function. This method works by iterating over each property of the object or element of the array and creating a new object or array with all nested objects and arrays also cloned.
Here’s an example of how you can do this using recursion:
function deepClone(obj) { if (Array.isArray(obj)) { // if obj is an array return obj.map(item => deepClone(item)); } else if (typeof obj === 'object' && obj !== null) { // if obj is an object let clonedObj = {}; for (let key in obj) { clonedObj[key] = deepClone(obj[key]); } return clonedObj; } else { // if obj is neither an array nor an object return obj; } }
In this function, we check whether the input obj
is an array or an object. If it’s an array, we use the map
function to create a new array with each element deep cloned recursively. If it’s an object, we create a new object and iterate through its properties, deep cloning each one recursively. If obj
is neither an array nor an object, we simply return it as is.
You can use this function to deep clone any object or array in JavaScript:
let originalObj = { name: 'John', age: 30, hobbies: ['reading', 'writing', 'coding'], address: { city: 'New York', state: 'NY', zip: '10001' } }; let clonedObj = deepClone(originalObj); console.log(originalObj === clonedObj); // false console.log(originalObj.hobbies === clonedObj.hobbies); // false console.log(originalObj.address === clonedObj.address); // false
In this example, we create an object originalObj
with some nested properties, and then deep clone it using our deepClone
function. We can see that the cloned object is completely independent of the original, since none of their properties share references.
Let me know your thoughts