Fundamental Concepts of Deep and Shallow Copy
Basic Definitions
Shallow Copy: Creates a new object and copies all property values from the original object to the new one. For reference-type properties (e.g., objects, arrays), it copies the reference address, meaning the new and original objects share these reference-type values.
Deep Copy: Creates a new object and recursively copies all property values from the original object. For reference-type properties, new reference-type objects are created, ensuring the new and original objects are completely independent and do not affect each other.
Why Copying is Needed
Copying operations are common in JavaScript development for several reasons:
- Avoiding Side Effects: Prevents modifications to the original object from impacting other parts of the code.
- Data Isolation: Maintains data independence when passing data between modules or components.
- State Management: Requires immutable data in state management libraries (e.g., Redux).
- Caching Mechanisms: Creates data snapshots for comparison or restoration.
Applicable Scenarios for Copying
| Scenario | Applicable Copy Type | Reason |
|---|---|---|
| Passing configuration objects | Shallow Copy | Configurations are typically flat structures, not requiring deep copying. |
| State management | Deep Copy | Requires a completely independent state tree. |
| Form data processing | Deep Copy | Prevents form modifications from affecting original data. |
| Caching mechanisms | Deep Copy | Needs fully independent data snapshots. |
| Component property passing | Shallow Copy | Usually involves simple data or component references. |
Shallow Copy Implementation Methods
Object.assign()
The Object.assign() method copies all enumerable own properties from one or more source objects to a target object.
const original = { a: 1, b: { c: 2 } };
const copy = Object.assign({}, original);
console.log(copy); // { a: 1, b: { c: 2 } }
copy.a = 3; // Modify primitive property
console.log(original.a); // 1 (unaffected)
copy.b.c = 4; // Modify reference-type property
console.log(original.b.c); // 4 (affected, shallow copy)Features:
- Copies only enumerable own properties.
- Copies reference addresses for reference-type properties.
- Accepts multiple source objects.
Spread Operator (...)
Introduced in ES6, the spread operator provides a concise way to perform shallow copying.
const original = { a: 1, b: { c: 2 } };
const copy = { ...original };
console.log(copy); // { a: 1, b: { c: 2 } }
copy.a = 3; // Modify primitive property
console.log(original.a); // 1 (unaffected)
copy.b.c = 4; // Modify reference-type property
console.log(original.b.c); // 4 (affected, shallow copy)Features:
- Concise and intuitive syntax.
- Performs only one-level shallow copying.
- Easily merges multiple objects.
Array.slice() and Array.concat()
For arrays, slice() or concat() methods can be used for shallow copying.
const originalArray = [1, 2, { a: 3 }];
const copyArray1 = originalArray.slice();
const copyArray2 = originalArray.concat();
console.log(copyArray1); // [1, 2, { a: 3 }]
console.log(copyArray2); // [1, 2, { a: 3 }]
copyArray1[2].a = 4; // Modify reference-type element
console.log(originalArray[2].a); // 4 (affected, shallow copy)Features:
- Copies only the first level of an array.
- Copies reference addresses for object elements.
- Does not affect primitive elements of the original array.
Limitations of Shallow Copy
The primary limitation of shallow copying is its inability to handle nested reference types:
const original = {
a: 1,
b: {
c: 2,
d: [3, 4]
}
};
const copy = { ...original };
copy.b.c = 5; // Modify nested object
copy.b.d.push(5); // Modify nested array
console.log(original.b.c); // 5 (affected)
console.log(original.b.d); // [3, 4, 5] (affected)



