ES6

Deep clone in Javascript

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