How to clone a JavaScript object ?

To copy/clone an object in JavaScript, you have the following options:

  1. spread (...)
  2. Object.assign()
  3. JSON.stringify() and JSON.parse()

JavaScript spread (...)

The spread operator (...) was introduced in ES6 allows you to copy all or part of an existing object/array into another object/array.
const colors = {'R': 'Red', 'G': 'Green','B': 'Blue'}; let copyColors = { ...colors }; copyColors.R = "Violet"
console.log(copyColors.R); //Violet ... changed console.log(copyColors); //{ R: 'Violet', G: 'Green', B: 'Blue' }
console.log(colors.R); //Red .... not changed console.log(colors); //{ R: 'Red', G: 'Green', B: 'Blue' }
When you check the above code, spread (...) operator perform a shallow copy. This means that the "R" value in the copyColors is changed but the original object "colors", you will notice it is not affected.

JavaScript Object.assign()

JavaScript Object.assign() method is used to copy or merge objects.
const colors = {'R': 'Red', 'G': 'Green','B': 'Blue'}; let copyColors = Object.assign({}, colors); copyColors.R = "Violet"
console.log(copyColors.R); //Violet ... changed console.log(copyColors); //{ R: 'Violet', G: 'Green', B: 'Blue' }
console.log(colors.R); //Red .... not changed console.log(colors); //{ R: 'Red', G: 'Green', B: 'Blue' }
When you check the above code, Object.assign() performs a shallow copy. This mean that it only copies properties, not prototype methods. Here, you can see, the "R" value in the copyColors is changed but the original object "colors", you will notice it is not affected.

JSON.parse()

For copying JavaScript object, you can use JSON.parse() alongside JSON.stringify().
const colors = {'R': 'Red', 'G': 'Green','B': 'Blue'}; let copyColors = JSON.parse(JSON.stringify(colors)); copyColors.R = "Violet"
console.log(copyColors.R); //Violet ... changed console.log(copyColors); //{ R: 'Violet', G: 'Green', B: 'Blue' }
console.log(colors.R); //Red ... not changed console.log(colors); //{ R: 'Red', G: 'Green', B: 'Blue' }
Above code shows that a deep copy allows you to create a completely independent copy of the original object.

Shallow Copy and Deep Copy


copy Javascript object

What is Shallow Copy?

In shallow copy, a new object is created that has an exact copy of the values in the original object. The reference pointers are also copied just like the values. Therefore, the references are pointing to the original objects. So, any changes to the members that are stored by reference appear in both the original and the copy, since no copy was made of the referenced object.

What is Deep Copy?

Deep copy makes a copy of all attributes of the old object and allocates separate memory addresses for the new object. So, any changes that are made to those referenced objects will not affect other copies of the object.

Here is an example of nested object/array.

const colors = { R: 'Red', G: 'Green', B: 'Blue', greenColors: { 'L':'limegreen', 'F':'forestgreen', }, };

Shallow Copy

When you used Javascrip spread (...) to copy an object, you are only creating a shallow copy. If the object/array is nested or multi-dimensional, it won't work. Let's copy/clone your object using spread(...).
const shallowCopyColors = { ...colors }; shallowCopyColors.R = 'Violet'; shallowCopyColors.greenColors.L = 'PaleGreen';

So here changed the cloned object by changing the 'R' value and nested 'L' value. Let's see the output.

console.log(shallowCopyColors);
//Output: { R: 'Violet', G: 'Green', B: 'Blue', greenColors: { L: 'PaleGreen', F: 'forestgreen' } }
console.log(colors);
//Output: { R: 'Red', G: 'Green', B: 'Blue', greenColors: { L: 'PaleGreen', F: 'forestgreen' } }
From the above code, you can understand that a shallow copy means the first level is copied, deeper levels are referenced.

Deep Copy

Let's take the same example but applying a deep copy using "JSON"
const deepCopyColors = JSON.parse(JSON.stringify(colors )); deepCopyColors.R = 'Violet'; deepCopyColors.greenColors.L = 'PaleGreen'; console.log(deepCopyColors);
//Output: { R: 'Violet', G: 'Green', B: 'Blue', greenColors: { L: 'PaleGreen', F: 'forestgreen' } }
console.log(colors);
//Output: { R: 'Red', G: 'Green', B: 'Blue', greenColors: { L: 'limegreen', F: 'forestgreen' } }
JSON.parse() will give you a deep copy. Above code shows that a deep copy allows you to create a completely independent copy of the original object. But it is important to note that the JSON.parse() alongside JSON.stringify() can be used for deep cloning but will not be the best option because it does not work with function or symbol properties. Whereas deep cloning work with all types, function and Symbol are copied by reference.