DEV Community

Shameel Uddin
Shameel Uddin

Posted on

Right way of cloning JavaScript Objects

Introduction

Cloning JS object is pretty common task in our day-to-day life. Lets discuss techniques about it.

PS. Use structuredClone for proper cloning as it's now available in native JS.

Shallow Cloning and Deep Cloning

Lets first discuss what actually is shallow cloning and deep cloning:

Shallow cloning and deep cloning are two different approaches to copying objects in JavaScript, and they have distinct characteristics and use cases:

Shallow Cloning:
Shallow cloning creates a new object, but it only copies the top-level properties of the original object. If the properties of the original object are references to other objects, those references are shared between the original and cloned objects.

Deep Cloning:
Deep cloning creates a completely new object with all of its properties and nested properties duplicated. It ensures that no references are shared between the original and cloned objects, resulting in a fully independent copy.

Shallow Cloning

1. Object.assign()

The Object.assign() method is a concise way to perform shallow cloning of JavaScript objects. It creates a new object and copies enumerable properties from the original object to the new one. However, be aware that if the properties in the original object are objects or arrays, they will be copied by reference.

const clonedObject = Object.assign({}, originalObject);
Enter fullscreen mode Exit fullscreen mode

2. Spread Operator (ES6)

The spread operator is another method for shallow cloning objects introduced in ES6. It provides a more modern and concise syntax for creating a shallow copy of an object.

const clonedObject = { ...originalObject };
Enter fullscreen mode Exit fullscreen mode

Deep Cloning

3. JSON.parse() and JSON.stringify()

To create a deep clone of an object, you can use JSON.parse() and JSON.stringify(). This method serializes the original object to a JSON string and then parses it back into a new object. It's great for deep cloning but has limitations, such as not handling functions, symbols, or circular references.

const clonedObject = JSON.parse(JSON.stringify(originalObject));
Enter fullscreen mode Exit fullscreen mode

4. Structured Clone

In web worker environments, you can use the structuredClone method to clone objects. This method can handle more complex data types but is specific to web workers.

Comparing Deep Cloning Methods

Let's say you have an object with a function property:

const originalObject = {
  name: "John",
  age: 30,
  greet: function () {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  },
};
Enter fullscreen mode Exit fullscreen mode

Now, let's try to clone this object using both methods: JSON.parse(JSON.stringify()) and structuredClone.

  1. Using JSON.parse(JSON.stringify()):
const cloneWithJSON = JSON.parse(JSON.stringify(originalObject));

// Attempt to call the function in the cloned object
cloneWithJSON.greet(); // Throws an error: cloneWithJSON.greet is not a function
Enter fullscreen mode Exit fullscreen mode

As you can see, the function property is lost during the cloning process. JSON.stringify serializes the object to JSON, and JSON.parse creates a new object from the JSON representation. Functions are not valid JSON, so they are omitted.

  1. Using structuredClone:
const clonedObject = structuredClone(originalObject);

// Attempt to call the function in the cloned object
clonedObject.greet(); // Works as expected: "Hello, my name is John and I am 30 years old."
Enter fullscreen mode Exit fullscreen mode

With structuredClone, the cloning process preserves the function property, and you can call it on the cloned object without any issues. This method is more powerful and versatile when working with complex objects that contain non-serializable properties.

Conclusion

  • For shallow cloning, consider using the spread operator or Object.assign() for their simplicity.

  • When deep cloning is required and your object doesn't contain functions, symbols, or circular references, opt for JSON.parse() and JSON.stringify().

  • structuredClone method is your best bet as it is now natively available and also helps cloning Dates, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays.

Follow me for more such content:
LinkedIn: https://www.linkedin.com/in/shameeluddin/
Github: https://github.com/Shameel123

Top comments (3)

Collapse
 
indrasisdatta profile image
indrasisdatta

Very nice article! I prefer using structuredClone in React projects. But recently faced this error in Next.js project "structuredClone is not defined". Any suggestions?

Collapse
 
shameel profile image
Shameel Uddin

Do confirm you node.js version. Is it 17 or newer?
Because structuredClone was introduced in nodejs 17.

Collapse
 
mrjohnsmith profile image
John Smith

Thats really great, even as I'm core php or Laravel developer but I always love to know about JS, may be my next stop is JS.