Overview
In JavaScript, copying objects or arrays can be categorized into shallow copy and deep copy. Understanding the difference is critical when dealing with complex data structures, especially those containing nested objects or arrays.
This guide explains these concepts, their characteristics, methods to implement them, and when to use each.
1. Shallow Copy
Definition
A shallow copy creates a duplicate of the top-level properties of an object or array. However, for nested objects or arrays, only the references are copied, not the actual data.
Characteristics
- Copies only the first level of properties or elements.
- Nested objects or arrays share references with the original object/array.
- Lightweight and efficient for simple structures but not suitable for independent duplication of nested data.
1.1 Using Object.assign()
const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, original);
shallowCopy.b.c = 42;
console.log(original.b.c); // OUTPUT: 42 (The original object also affected due to shared reference)
1.2 Using the Spread Operator (...)
const original = { a: 1, b: { c: 2 } };
const shallowCopy = { ...original };
shallowCopy.b.c = 90;
console.log(original.b.c); // OUTPUT: 90
1.3 Lets see an example of shallow copy on Array Methods (slice, concat)
const original = [1, 2, [3, 4]];
const shallowCopy = original.slice();
shallowCopy[2][0] = 10;
console.log(original[2][0]); // OUTPUT: 10
2. Deep Copy
Definition
A deep copy creates a fully independent duplicate of an object or array. All levels, including nested structures, are recursively copied. Changes to the copied structure do not affect the original, and vice versa.
Characteristics
- Recursively copies all levels of the structure.
- Nested objects or arrays are independent of the original.
- Computationally heavier than shallow copies.
2.1 Using JSON.stringify()
and JSON.parse()
- Converts the object into a JSON string and then back into a new object.
- Limitations: Does not handle functions, Date, RegExp, or circular references.
const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.b.c = 42;
console.log(original.b.c); // OUTPUT: 2 (original remains unaffected)
2.2 Using structuredClone()
A modern method for deep copying that supports circular references and special objects like Date.
const original = { a: 1, b: { c: 2 }, date: new Date() };
const deepCopy = structuredClone(original);
deepCopy.b.c = 42;
console.log(original.b.c); // OUTPUT: 2
console.log(original.date === deepCopy.date); // FALSE
2.3 Using a Custom Recursive Function
A flexible solution for handling complex cases manually.
function deepCopy(obj) {
if (obj === null || typeof obj !== "object") return obj;
if (Array.isArray(obj)) return obj.map(deepCopy);
const copy = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepCopy(obj[key]);
}
}
return copy;
}
const original = { a: 1, b: { c: 2 } };
const deepCopyObj = deepCopy(original);
deepCopyObj.b.c = 42;
console.log(original.b.c); // OUTPUT: 2
3. When to Use Each?
Shallow Copy
- For flat objects or arrays without nested structures.
- When performance is critical, and shared references for nested objects are acceptable.
Deep Copy
- For complex, deeply nested objects/arrays.
- When you need true independence between the copy and the original.
4. Summary
Shallow Copy
- Simple and efficient.
- Suitable for flat structures or when shared references are acceptable.
Deep Copy
- Robust and ensures full independence.
- Ideal for deeply nested or complex structures.
This is an in depth explanation of the Shallow copy and Deep copy of objects in the JavaScript. Choose the appropriate method based on your use case and performance requirements.
Top comments (0)