Summary: in this tutorial, you will learn how to copy objects in JavaScript, including shallow copy and deep copy. To copy an object in JavaScript, you have three options:
const obj = { a: 1,b: 2};
//1.Using spread ...
const clone1 = {...obj};
//2.Using Object.assign() method
const clone2 = Object.assign({},obj);
//3.Using JSON
const clone3 = JSON.parse(JSON.stringify(obj));
Both spread (...
) and Object.assign()
perform a shallow copy while the JSON methods carry a deep copy.
1.Shallow copy vs. deep copy
In JavaScript, you use variables to store values that can be primitive or references. When you make a copy of a value stored in a variable, you create a new variable with the same value. For a primitive value, you just simply use a simple assignment:
let counter = 1;
let copiedCounter = counter;
And when you change the value of the copied variable, the value of the original remains the same.
copiedCounter = 2;
console.log(counter); // 1
However, if you use the assignment operator for a reference value, it will not copy the value. Instead, both variables will reference the same object in the memory:
let obj = { a: 1,b: 2 };
let copiedObj = obj;
And when access the object via the new variable (copiedObj ) and change the value of its property (a), you change the value of the property of the object.
copiedObj.a = 10;
console.log(obj); // { a: 10,b: 2 };
A deep copying means that the value of the new variable is disconnected from the original variable while a shallow copy means that some values are still connected to the original variable.
2.Shallow copy example
const obj = {a:1,b:2,c:{d:3}};
const shallowClone = {...obj};
shallowClone.c.d = 34; // connected
console.log(obj); // {a:1,b:2,c:{d:34}}
console.log(shallowClone); // {a:1,b:2,c:{d:34}}
In this example, c
is a reference value while a
, b
is a primitive value. Both obj
and shallowClone
references different objects but these objects reference the same c
object
3.Deep copy example
const obj = {a:1,b:2,c:{d:3}};
const deepClone = JSON.parse(JSON.stringify(obj));
deepClone.c.d = 34; //disconected
console.log(obj); // {a:1,b:2,c:{d:3}}
console.log(deepClone); // {a:1,b:2,c:{d:34}}
In this example, all values in the deepClone
object is disconnected from the original ojb
object.