DEV Community

VivekSinh Rajput
VivekSinh Rajput

Posted on

what is shallow copy and deep copy in TS...

Deep Copy vs Shallow Copy in JavaScript

In JavaScript, when you copy an object or array, you might either perform a shallow copy or a deep copy. Understanding the difference is crucial, especially when dealing with complex data structures.


Memory and References Basics

JavaScript objects and arrays are reference types. When you assign an object or array to a variable, you're assigning a reference to its memory location, not the actual data.

  • Primitive types (e.g., string, number, boolean) are stored by value.
  • Non-primitive types (e.g., object, array, function) are stored by reference.

Shallow Copy

A shallow copy duplicates the top-level properties but references any nested objects or arrays. Changes to the nested objects in the copy affect the original.

How It Works

  • Copies only the first level of the object/array.
  • Nested objects/arrays share the same reference.

Pitfall

When you modify a nested object in the copy, it also modifies the original object because they share the same memory reference.

Examples

1. Shallow Copy with Arrays

const arr = [1, 2, [3, 4]];

const shallowCopy = arr.slice(); // or [...arr]

shallowCopy[0] = 100;
console.log(arr); // [1, 2, [3, 4]] -> top-level unaffected

shallowCopy[2][0] = 999;
console.log(arr); // [1, 2, [999, 4]] -> nested array modified
Enter fullscreen mode Exit fullscreen mode

2. Shallow Copy with Objects

const obj = { a: 1, b: { c: 2 } };

const shallowCopy = { ...obj };

shallowCopy.a = 100;
console.log(obj); // { a: 1, b: { c: 2 } } -> top-level unaffected

shallowCopy.b.c = 999;
console.log(obj); // { a: 1, b: { c: 999 } } -> nested object modified
Enter fullscreen mode Exit fullscreen mode

Key Takeaway

  • Top-level properties are copied by value.
  • Nested structures are copied by reference.

Shallow Copy Methods

  • Arrays: Array.prototype.slice(), spread operator ([...arr]).
  • Objects: Object.assign(), spread operator ({...obj}).

Deep Copy

A deep copy creates a new object or array with completely independent copies of the original structure, including all nested levels.

How It Works

  • Recursively copies all levels of an object or array.
  • Nested objects/arrays get independent copies.

Safe from Mutation

Changes in the copied object or array do not affect the original.

Examples

1. Deep Copy with structuredClone()

const arr = [1, 2, [3, 4]];

const deepCopy = structuredClone(arr);
deepCopy[2][0] = 999;

console.log(arr); // [1, 2, [3, 4]] -> original remains intact
console.log(deepCopy); // [1, 2, [999, 4]]
Enter fullscreen mode Exit fullscreen mode

2. Deep Copy with JSON.parse(JSON.stringify())

const obj = { a: 1, b: { c: 2 } };

const deepCopy = JSON.parse(JSON.stringify(obj));
deepCopy.b.c = 999;

console.log(obj); // { a: 1, b: { c: 2 } } -> original intact
console.log(deepCopy); // { a: 1, b: { c: 999 } }
Enter fullscreen mode Exit fullscreen mode

Limitations of JSON.parse(JSON.stringify())

  • Loses functions and undefined values.
  • Doesn't handle Date, RegExp, Map, Set, BigInt, or Symbol.

Key Differences

Aspect Shallow Copy Deep Copy
Copy Depth Only the first level All nested levels
Nested Changes Affect the original object Do not affect original
Performance Faster for small objects Slower due to recursion
Complexity Simple and native methods Complex with recursion
Methods spread, slice, Object.assign structuredClone, JSON.parse(JSON.stringify())

When to Use What?

  1. Shallow Copy:

    • When you need to copy simple objects with no nested structure.
    • When performance is more critical than integrity of nested data.
  2. Deep Copy:

    • When working with complex nested objects.
    • When the copied object needs complete independence.

In-Depth Mechanics

Shallow Copy Mechanics

  1. Create a new object/array.
  2. Copy primitive values by value.
  3. Copy objects/arrays by reference.

Example:

const obj = { x: 1, y: { z: 2 } };
const shallow = { ...obj };
Enter fullscreen mode Exit fullscreen mode

Memory layout:

  • shallow.x: New primitive copy.
  • shallow.y: Same reference as obj.y.

Deep Copy Mechanics

  1. Recursively iterate through each property.
  2. Copy primitive values by value.
  3. Recursively copy objects/arrays by creating new instances.

Example:

function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (Array.isArray(obj)) return obj.map(deepClone);

  const newObj = {};
  for (let key in obj) {
    newObj[key] = deepClone(obj[key]);
  }
  return newObj;
}
Enter fullscreen mode Exit fullscreen mode

Memory layout:

  • Every level is independently copied.

Performance Consideration

Deep copies take more time and resources compared to shallow copies due to the recursive nature of traversing nested structures.

Benchmark:

console.time('shallow');
const shallowCopy = [...Array(100000).keys()];
console.timeEnd('shallow');

console.time('deep');
const deepCopy = JSON.parse(JSON.stringify(Array(100000).fill({ x: 1 })));
console.timeEnd('deep');
Enter fullscreen mode Exit fullscreen mode

Conclusion

  • Shallow Copy: Efficient but risky with nested objects.
  • Deep Copy: Safe but more resource-intensive.

For modern applications, structuredClone() is recommended for deep copies, as it avoids many limitations of JSON.parse(JSON.stringify()).

Top comments (0)