2 min read

Deep Copy vs. Shallow Copy

When copying objects and arrays in JavaScript, it is important to understand whether you are creating a shallow copy or a deep copy. This distinction arises because objects are reference types.

1. Shallow Copy

A shallow copy creates a new object, but it copies the references of nested objects, not the actual nested objects themselves.

  • Primitives: Copied by value.
  • Nested Objects: Copied by reference (shared between original and copy).

Methods to create a Shallow Copy

  1. Spread Syntax (...)
  2. Object.assign()
  3. Array.prototype.slice()

Example

const original = {
  name: "Alice",
  address: {
    city: "New York"
  }
};

const shallowCopy = { ...original };

// Modifying a primitive property
shallowCopy.name = "Bob";
console.log(original.name); // "Alice" (Unaffected)

// Modifying a nested object
shallowCopy.address.city = "Los Angeles";
console.log(original.address.city); // "Los Angeles" (Affected!)

Because address is an object, both original and shallowCopy point to the same address object in memory.

2. Deep Copy

A deep copy creates a new object and recursively copies all nested objects. The original and the copy are completely independent.

Methods to create a Deep Copy

1. JSON.parse(JSON.stringify())

The classic "hack". It converts the object to a string and back.

  • Pros: Simple, works for basic data.
  • Cons: Fails with Date, undefined, Infinity, RegExp, Map, Set, and functions.
const deepCopy = JSON.parse(JSON.stringify(original));

2. structuredClone() (Modern Standard)

A built-in function available in modern browsers and Node.js.

  • Pros: Handles Date, Map, Set, RegExp, Infinity.
  • Cons: Cannot clone functions or DOM nodes.
const original = {
  name: "Alice",
  date: new Date(),
  address: { city: "New York" }
};

const deepCopy = structuredClone(original);

deepCopy.address.city = "London";
console.log(original.address.city); // "New York" (Unaffected)

3. Libraries (Lodash)

Libraries like Lodash provide robust deep cloning.

import _ from 'lodash';
const deepCopy = _.cloneDeep(original);

programming/javascript/vanilla/javascript programming/javascript/vanilla/pass-by-value-vs-reference programming/javascript/vanilla/data-types