Deep Cloning Objects in JavaScript
Published: 2024-01-09 17:15:56

A lot of the developers are still not aware of the the method to deep clone objects in JavaScript the native way. 
Thats right, `structuredClone` method is built-in:

```js
const song = {
    title: 'Never gonna give you up',
    artist: 'Rick Astley'
}

const copiedSong = structuredClone(song);
```

JavaScript's `structuredClone` method serves as a powerful tool for creating exact, deep copies of complex data structures and objects within the language. Unlike conventional cloning methods, `structuredClone` can duplicate not only simple data types but also intricate objects, arrays, and nested elements, ensuring their integrity while preserving references. Whether dealing with intricate data structures or nested objects, `structuredClone` provides developers with a reliable means to duplicate JavaScript entities without compromising their structure or integrity.

It can clone a wide variety of JavaScript types:

* Array
* Date
* Set
* Map
* Blob
* [And many more](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types)

## [Let's look at _JSON.parse(JSON.stringify(x))_](#lets-look-at-jsonparsejsonstringifyx)

This hack works perfectly well for all situations, but still has some drawbacks, which are addressed by the `structuredClone`.

```js
const song = {
    title: 'Never gonna give you up',
    artist: 'Rick Astley',
    tags: ['pop'],
    releaseDate: new Date()
};

const probalamaticCopiedSong = JSON.parse(JSON.stringify(song));

console.log(probalamaticCopiedSong);
```

The above example we are trying to use the hack to copy the `song` object with a key which is of type `Date` but when we try to log the copied object we get the following:

```json
{
  title: 'Never gonna give you up',
  artist: 'Rick Astley',
  tags: [ 'pop' ],
  releaseDate: '2024-01-09T17:01:05.013Z'
}
```
The `releaseDate` key is converted to string and is not the desired result, we want the `Date` to remain as a `Date`.

## [What about spread operator?](#what-about-spread-operator)

Understanding what a deep copy means is important here, if we want a shallow copy the spread operator serves the purpose, basically not being able to copy the nested elements of an object. 

```js
const song = {
    title: 'Never gonna give you up',
    artist: 'Rick Astley'
};

const copiedSong = {...song};
```
The above works perfectly fine. Until, we introduce a third key to our `song` object and try to copy it usign the spread method.

```js
const song = {
    title: 'Never gonna give you up',
    artist: 'Rick Astley',
    tags: ['pop']
};

const shallowCopiedSong = {...song};

shallowCopiedSong.tags.push('rick roll');
```
Lets look at the same example again with some change, here when we try to push a string value to the `tags` key on the `shallowCopiedSong` object, not only it will add `'rick roll'` to `shallowCopiedSong` it will also add it to the `song` object, and that is not the solution we are looking for.

## [Browser Compatibility](#browser-compatibility)

![browser compatibility of structuredClone](https://raw.githubusercontent.com/shubhambattoo/blog-assets/main/structuredClone-compatibility.png)

Source: [MDN](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone#browser_compatibility)

## [Conclusion](#conclusion)

In the ever-evolving realm of JavaScript, structuredClone emerges as a pivotal feature, enabling developers to faithfully replicate intricate data structures and objects while maintaining their integrity. Its ability to create precise duplicates of complex entities empowers developers, ensuring the preservation of relationships and facilitating seamless data manipulation within JavaScript applications.