Right way of cloning JavaScript Objects
Tags: webdev, javascript, react, node
Published: 2023-09-20 06:36:09

## 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.

```javascript
const clonedObject = Object.assign({}, originalObject);
```

**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.

```javascript
const clonedObject = { ...originalObject };
```

## 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.

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

**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:

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

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

1. Using `JSON.parse(JSON.stringify())`:

```javascript
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
```

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.

2. Using `structuredClone`:

```javascript
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."
```

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