You might be thinking about why you cannot copy an object directly by assigning it to another variable. The reason is that the variable that holds the object is called the reference variable. It points to the object stored in the memory. When you copy an object using an equals sign, JavaScript copies the reference to the object to the new variable. After that, both the variables point to the same object. And then, if a new variable makes changes to the object, it will be reflected in the original variable.
let pdt = { name:'Google Nest Mini', quantity: 30 } let product = pdt; product.name = 'Amazon Echo Dot'; console.log(pdt); //{name:'Amazon Echo Dot', quantity:30} console.log(product); //{name:'Amazon Echo Dot', quantity:30}
In this example, you can see that the variable product
has updated the name
property of an object and that change is reflected in the original object pdt
. That is why you need different ways to clone objects.
In JavaScript, there are three ways of copying objects:
Note: The spread operator and Object.assign()
method perform shallow copy whereas JSON.stringify()
and JSON.parse()
methods perform deep copy.
Before you start learning the different methods of copying objects, you must understand shallow copy and deep copy.
When you shallow copy an object, only top-level properties are duplicated. All the nested properties are shared between the copied and original variables.
When you deep copy an object, all the properties, including top-level and nested, are duplicated. Nothing is shared between the copied and original variables.
Using ES6 spread operator, you can clone objects. The procedure for doing this is straightforward. All you have to do is start by typing opening curly braces, then three ellipses followed by an object you want to clone; in the end, type closing curly braces.
let copiedObject = {...obj};
Let's clone an object using the spread operator.
let pdt = { name:'Google Nest Mini', price: 49.00, generation: '2nd Gen', features:{ voiceSupport: 'Google Assistant' } } let product = {...pdt}; product.name = 'Amazon Echo Dot'; console.log(pdt); console.log(product);
Output
{ name:'Google Nest Mini', price: 49.00, generation: '2nd Gen', features:{ voiceSupport: 'Google Assistant' } } { name:'Amazon Echo Dot', price: 49.00, generation: '2nd Gen', features:{ voiceSupport: 'Google Assistant' } }
As you can see, if we modify the top-level properties of the product
object, there is no change in the original object pdt
.
It is important to note that the spread operator performs the shallow copy, which means nested properties are shared between the original and the copied object.
let pdt = { name:'Google Nest Mini', price: 49.00, generation: '2nd Gen', features:{ voiceSupport: 'Google Assistant' } } let product = {...pdt}; product.name = 'Amazon Echo Dot'; product.features.voiceSupport = 'Amazon Alexa'; console.log(pdt); console.log(product);
Output
{ name:'Google Nest Mini', price: 49.00, generation: '2nd Gen', features:{ voiceSupport: 'Amazon Alexa' } } { name:'Amazon Echo Dot', price: 49.00, generation: '2nd Gen', features:{ voiceSupport: 'Amazon Alexa' } }
From this example, it is clear that both pdt.features
and product.features
are sharing the same reference.
Apart from merging two or more objects, Object.assign()
method is also used to copy an object. The process for copying an object using Object.assign() method is:
let copiedObject = Object.assign({}, originalObject);
The copy operation performed by Object.assign() method is shallow in nature, which means when you update nested properties, the change will reflect in both the copied and original variables.
let pdt = { name:'Google Nest Mini', price: 49.00, generation: '2nd Gen', features:{ voiceSupport: 'Google Assistant' } } let product = Object.assign({}, pdt); product.name = 'Amazon Echo Dot'; product.features.voiceSupport = 'Amazon Alexa'; console.log(pdt); console.log(product);
The example is the same as shown in the spread operator. However, instead of the spread operator, Object.assign()
method is used.
JSON.stringify()
method converts JavaScript object to JSON string. You have to pass this JSON string to JSON.parse()
method, converting it to the same JavaScript object. And in this way, you copy an object. This method does deep copy.
let pdt = { name:'Google Nest Mini', price: 49.00, generation: '2nd Gen', features:{ voiceSupport: 'Google Assistant' } } let product = JSON.parse(JSON.stringify(pdt)); product.name = 'Amazon Echo Dot'; product.features.voiceSupport = 'Amazon Alexa'; console.log(pdt); console.log(product);
Output
{ name:'Google Nest Mini', price: 49.00, generation: '2nd Gen', features:{ voiceSupport: 'Google Assistant' } } { name:'Amaon Exho Dot', price: 49.00, generation: '2nd Gen', features:{ voiceSupport: 'Amazon Alexa' } }
In this example, features
property is not shared between the product
and pdt
objects.