When it comes to copying objects in JavaScript, it can get tricky, especially if you want to perform a deep clone. Deep cloning ensures that not only the primitive types like numbers and strings are copied, but also the referenced objects are recursively copied to create a completely independent cloned object. In this blog post, we will explore different options for deep cloning a JavaScript object.

Deep Copy vs Shallow Copy

A shallow copy in JavaScript only copies the references to external objects, while a deep copy also copies the referenced objects. This means that if an object references other objects, a shallow copy will only copy the references, while a deep copy will create new copies of those external objects as well.

Easiest Option: Use Lodash

One of the easiest and most reliable ways to perform deep copying in JavaScript is by using a library called Lodash. Lodash offers the clone and cloneDeep functions specifically designed for shallow and deep cloning, respectively. These functions are well-tested and widely used in the JavaScript community.

const clone = require('lodash.clone');
const cloneDeep = require('lodash.clonedeep');

To use Lodash for deep cloning, you can simply call the cloneDeep function with the object you want to clone as the argument.

const originalObject = {
  name: 'John',
  age: 30,
  hobbies: ['reading', 'hiking'],
};

const clonedObject = cloneDeep(originalObject);

Lodash’s deep cloning ensures that any changes made to the cloned object will not affect the original object or its referenced objects.

Object.assign()

While Object.assign() is commonly used for copying objects in JavaScript, it performs a shallow copy, not a deep clone. It copies the values of the properties from the source object to the target object, but the properties that are objects themselves are still referenced.

const copiedObject = Object.assign({}, originalObject);

If you modify an object property in the original object after copying, the change will also be reflected in the copied object, since they both reference the same inner object.

Using the Object Spread Operator

The Object Spread operator introduced in ES6 provides a concise way to perform a shallow clone similar to Object.assign(). However, it does not perform a deep clone.

const copiedObject = { ...originalObject };

Like Object.assign(), the Object Spread operator only copies the values of the properties, while the properties that are objects themselves are still referenced.

Wrong Solutions

There are some commonly suggested solutions for deep cloning in JavaScript that are incorrect and should not be used.

Using Object.create()

Using Object.create() to clone an object is not recommended because it does not perform any copy. Instead, the original object is used as the prototype of the cloned object, resulting in a new object that inherits properties from the original object.

const copiedObject = Object.create(originalObject);

Even though this might seem to work, it’s not a true copy, and any changes made to the original object will be reflected in the cloned object.

JSON Serialization

Another incorrect solution that is sometimes suggested is to use JSON serialization and deserialization. While this approach might work for simple objects, it has some drawbacks.

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

Using JSON serialization and deserialization can cause the loss of certain JavaScript-specific types, such as functions or Infinity values. Additionally, some objects are converted to strings during the serialization process, which may lead to unexpected behavior.

In conclusion, when it comes to deep cloning a JavaScript object, it’s best to rely on a well-tested and widely used library like Lodash. Using Lodash’s cloneDeep function ensures a proper deep clone without any unexpected side effects.