The Most Efficient Ways to Clone objects in JavaScript
Tags: javascript, webdev, beginners
Published: 2021-08-20 13:55:26

Cloning objects is one of the most commonly used operations in the JavaScript universe. In this article, we will dive into different types of cloning that exist in JavaScript (Node.js and Browser environment). We will also discuss the most efficient ways to shallow and deep clone objects in JavaScript.

> 📝 There are many blog posts, articles, and stack overflow threads that exist on this topic already. This article is my attempt to put the collective knowledge of the internet into one composed summary that is easy to follow and reference.

Let’s dive in 🏄‍♀️

## Native deep cloning

Native deep cloning is known as “structured cloning” in Node.js. This feature is not available in the browser. Structured cloning supports an additional set of data types along with the ones that are supported by JSON. Here’s a list of additional data types it supports. Here’s an example of native deep cloning below:

```js
const v8 = require('v8');
const structuredClone = obj => {
 return v8.deserialize(v8.serialize(obj));
};
 
let sampleObject = {
 hello: 'hello',
 a: 'worlds',
 nested: {
   first: 'first object value'
 }
};
let cloned = structuredClone(sampleObject);
```


## JSON.parse/stringify — cloning with data loss

Good ol’ JOSN.stringify() is the most used method for cloning an object when you don’t care about data loss or shallow clone is sufficient for your use case. Here’s a simple example

```js
let some_obj = {
 name: "Shadid Haque",
 age: 26,
 items: ["health portion", "bow", "arrow"]
}

let copy = JSON.parse(JSON.stringify(some_obj));
console.log(copy)
```

Applying JSON.strigify() causes data loss when the object to be copied has complex data or functions nested. Here’s an example where data loss happens on JSON.strigify().

```js
let objA = {
  name: "Super Man",
  attack: () => {
    console.log("damage++");
  }
};

const copy = JSON.parse(JSON.stringify(objA));
console.log(copy);
```
## Spread Operations — shallow clone

Spread operation is the easiest way to clone a object in ES6. Data loss happens on this method as well. However, since this is native to ES6 it is more performant than JSON.strigify().

> Checkout the benchmark [here] (https://jsben.ch/bWfk9).

Here’s an example of cloning with spread operator

```js
let A1 = {a: "2"};
let A3 = {...A1};  // Spread Syntax
```

## Object.assign()

Object.assign() is an ES6 method that allows shallow cloning simmilar to spread operation.

```js
let obj = {a: "2"};
let objCopy = Object.assign({}, obj);
```

## Deep Cloning with lodash library

If you are looking for a reliable deep cloning method and don’t mind using a third party library then lodash might just be the solution you are looking for.

```js

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

let objects = [{ 'Hensen': 1 }, { 'Jon': 2 }];
 
let deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
```

## Deep cloning with custom function

Finally, we can roll out our own function for deep copying an object. I found the following code snippet from stack overflow and I have been using it in my projects.

```js
function clone(obj) {
    if (obj === null || typeof (obj) !== 'object' || 'isActiveClone' in obj)
        return obj;

    if (obj instanceof Date)
        let temp = new obj.constructor(); 
    else
        let temp = obj.constructor();

    for (let key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            obj['isActiveClone'] = null;
            temp[key] = clone(obj[key]);
            delete obj['isActiveClone'];
        }
    }
    return temp;
}
```

If you are concerned about performance of various cloning functions I highly suggest you take a look at this following thread. I hope this article was helpul. That’s all for today 🙂, until next time

### References

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types

https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript/5344074#5344074

https://www.npmjs.com/package/lodash.clonedeep