Lesson 34-Implementation and Underlying Principles of JS deep and Shallow Copy

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:

  1. Avoiding Side Effects: Prevents modifications to the original object from impacting other parts of the code.
  2. Data Isolation: Maintains data independence when passing data between modules or components.
  3. State Management: Requires immutable data in state management libraries (e.g., Redux).
  4. Caching Mechanisms: Creates data snapshots for comparison or restoration.

Applicable Scenarios for Copying

ScenarioApplicable Copy TypeReason
Passing configuration objectsShallow CopyConfigurations are typically flat structures, not requiring deep copying.
State managementDeep CopyRequires a completely independent state tree.
Form data processingDeep CopyPrevents form modifications from affecting original data.
Caching mechanismsDeep CopyNeeds fully independent data snapshots.
Component property passingShallow CopyUsually 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)

Membership Required

You must be a member to access this content.

View Membership Levels

Already a member? Log in here

Share your love