Skip to content

Deep Cloning Objects In JavaScript

In this article, we are going to discuss deep cloning objects in JavaScript. In JavaScript, Object play a major role in storing and sharing data.

Because objects in JavaScript are references values, we can’t simply just copy using the =. So your first question might be, why can’t I use =. Let’s see what happens if we do that:

const obj = { "Red Apple": "🍎", "Green Apple": "🍏" };
const obj2 = obj;

console.log(obj); //{ "Red Apple": "🍎", "Green Apple": "🍏" }
console.log(obj2);//{ "Red Apple": "🍎", "Green Apple": "🍏" }

So now, we can see what happens when we manipulate the copied object(obj2) in the below code snippet

obj2["Grapes"] = "🍇";

console.log(obj); 
//{ "Red Apple": "🍎", "Green Apple": "🍏", "Grapes": "🍇"}
console.log(obj2);
//{ "Red Apple": "🍎", "Green Apple": "🍏", "Grapes": "🍇"}

I have changed obj2 but why was obj also mutated. That’s because Objects are reference types. So when we use =, it copied the pointer to the memory space it occupies.

Reference types don’t hold values, they are a pointer to the value in memory. But no worries, here are 3 ways for you to clone an object😉

1. Using Spread

Using spread will clone your object. Note this will be a shallow copy.

const animal = { Dog: '🐶', Monkey: '🐒' };

const cloneAnimal = { ...animal };

console.log(cloneAnimal);
// { Dog: '🐶', Monkey: '🐒' }

2. Using Object.assign

And it’s also a shallow copy. Note the empty {} as the first argument, this will ensure you don’t mutate the original object 👍

const animal = { Dog: '🐶', Monkey: '🐒' };

const cloneAnimal = Object.assign({}, animal);

console.log(cloneAnimal);
// { Dog: '🐶', Monkey: '🐒' }

3. Using JSON

And this will be the final way gives us the deep copy. For a more robust solution, I would recommend using something like lodash

const animal = { Dog: '🐶', Monkey: '🐒' };

const cloneAnimal = JSON.parse(JSON.stringify(animal));

console.log(cloneAnimal);
// { Dog: '🐶', Monkey: '🐒' }

Shallow Clone vs Deep Clone

When we do the Shallow copy using the spread(…) and Object.assign it doesn’t work for nested object. A shallow copy means the first level is copied, deeper levels are referenced.

const nestedObject = {animal: '🐶', property: {color: 'black'}};

const shallowCloneObj = { ...nestedObject };
shallowCloneObj.property.color = 'white';

console.log(shallowCloneObj); 
// {animal: '🐶', property: {color: 'white'}};
console.log(nestedObject);    
// {animal: '🐶', property: {color: 'white'}}; <-- ☹️

Let’s take the same example but applying a deep copy using “JSON”

const nestedObject = {animal: '🐶', property: {color: 'black'}};

const shallowCloneObj = JSON.parse(JSON.stringify(nestedObject));
shallowCloneObj.property.color = 'white';

console.log(shallowCloneObj); 
// {animal: '🐶', property: {color: 'white'}};
console.log(nestedObject);    
// {animal: '🐶', property: {color: 'black'}}; <-- 👍

As we see, the deep copy is a true copy for nested objects. Often time shallow copy is good enough, you don’t really need a deep copy.

See also  Defining variables inside the If statement in JavaScript

It’s all up to you, is it fine to mutate your original object then you can go with shallow copy. Otherwise, you can use deep copy.

For More Reference

Happy Coding 🙂

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.