Table of contents
Introduction
Shallow copies
Deep copies
Spread syntax
Deep copying objects
JSON.stringify() and JSON.parse()
structuredClone()
Conclusion
Introduction
When copying objects in JavaScript, it is important to understand the difference between shallow
and deep copies
.
A shallow copy
creates a new object that contains the same properties as the original object, but the values of those properties may still refer to the same memory locations as the original object.
On the other hand, A deep copy
,copies all the fields with dynamically allocated memory. That is, every value of the copied object gets a new memory locations rather than the original object.
But when should you opt for a shallow copy, and when is a deep copy more appropriate? The answer hinges on your specific needs:
Shallow copies
are the choice when you want to create a new object that shares the same data as the original object, but you don't need to modify the original object. For example, you might use a shallow copy to create a new object to pass to a function as an argument.Deep copies
come into play when you need to create a new object that is completely independent of the original object. For example, you might use a deep copy to create a new object that you will be modifying, and you don't want those modifications to affect the original object
Spread syntax
The spread syntax (...
) is a new feature in JavaScript that allows you to expand arrays and objects. When used with objects, the spread syntax only deep copies the top level data of an object. Nested objects are shallow copied, meaning that they will still refer to the same memory locations as the original object. This can be a problem if you need to create a completely independent copy of the object.
Example:
const oldObj = {
a: { b: 10 },
c: 20,
};
const newObj = { ...oldObj };
oldObj.a.b = 30; // This also changes the newObj.a.b value to 30, because they both refer to the same memory location.
oldObj.c = 40; // This changes the oldObj.c value, but the newObj.c value remains 20.
console.log(newObj);
// Output: { a: { b: 30 }, c: 20 }
In the above example, when we create the newObj
object using the spread syntax, we are creating a shallow copy of the oldObj
object. This means that the newObj
object will have the same properties as the oldObj
object, but the values of any nested objects will still refer to the same memory locations as the original object.
When we change the value of the b
property on the oldObj
object, the value of the b
property on the newObj
object also changes, because they both refer to the same memory location. However, when we change the value of the c
property on the oldObj
object, the value of the c
property on the newObj
object does not change, because the c
property on the newObj
object is referring to a new copy of the object.
Deep copying objects
If you need to create a deep copy of an object, you can use one of the following methods:
- JSON.stringify() and JSON.parse()
The JSON.stringify()
and JSON.parse()
methods can be used to create a deep copy of an object. The JSON.stringify()
method converts an object to a JSON string, and the JSON.parse()
method converts a JSON string back to an object.
const oldObj = { a: { b: 10 } };
const newObj = JSON.parse(JSON.stringify(oldObj));
console.log(newObj);
// Output: { a: { b: 10 } }
oldObj.a.b = 20;
console.log(newObj);
// Output: { a: { b: 10 } }
As you can see, when we change the value of the b
property on the oldObj
object, the value of the b
property on the newObj
object does not change. This is because the JSON.parse()
method creates a deep copy of the object, and the b
property on the newObj
object is referring to a new memory location.
- structuredClone()
The structuredClone()
method is a new method in JavaScript that creates a deep copy of an object. The structuredClone()
method is similar to the JSON.stringify()
and JSON.parse()
methods, but it is more efficient and can handle a wider range of object types.
const oldObj = { a: { b: 10 } };
const newObj = structuredClone(oldObj);
console.log(newObj);
// Output: { a: { b: 10 } }
oldObj.a.b = 20;
console.log(newObj);
// Output: { a: { b: 10 } }
As you can see, when we change the value of the b
property on the oldObj
object, the value of the b
property on the newObj
object does not change. This is because the structuredClone()
method creates a deep copy of the object, and the b
property on the newObj
object is referring to a new memory location.
Conclusion
The spread syntax (...
) is a convenient way to create shallow copies of objects. However, if you need to create a deep copy of an object, you should use one of the following methods:
JSON.stringify()
andJSON.parse()
structuredClone()
The structuredClone()
method is the most efficient and robust way to create a deep copy of an object.