Skip to main content

How do you make a deep copy of an object?

What a "deep copy" is

A deep copy is when a fully independent object is created, including all nested objects and arrays. Changes to the copy do not affect the original.


1. The modern way - structuredClone()

The most reliable and simplest method (available in all modern browsers and Node.js 17+).

javascript
const user = { name: 'Alice', address: { city: 'Kyiv', zip: 12345 }, tags: ['dev', 'frontend'] }; const clone = structuredClone(user); clone.address.city = 'Lviv'; clone.tags.push('react'); console.log(user.address.city); // "Kyiv" console.log(user.tags); // ['dev', 'frontend']

Advantages:

  • Copies objects, arrays, dates, Map, Set and others.
  • Safe and fast.

Limitations:

  • Does not copy functions and prototypes (they are lost).
  • Does not support undefined as a key (but supports it as a value).

2. Via JSON.parse(JSON.stringify())

A classic approach that works everywhere, even in older browsers:

javascript
const user = { name: 'Alice', address: { city: 'Kyiv' }, tags: ['frontend', 'dev'] }; const clone = JSON.parse(JSON.stringify(user)); clone.address.city = 'Lviv'; console.log(user.address.city); // "Kyiv"

Advantages:

  • Simple and universal.

Disadvantages:

  • Loses:
    • functions;
    • undefined, Symbol, BigInt;
    • Date, Map, Set, RegExp (turned into plain objects/strings).
  • Slower on very large objects.

3. With Lodash (_.cloneDeep())

If the project is large or uses TypeScript, this is the most reliable option.

javascript
import _ from 'lodash'; const clone = _.cloneDeep(user);

Advantages:

  • Deeply copies any data type (including Date, Map, Set, Buffer, etc.).
  • Works reliably in all environments.

Disadvantage:

  • Requires installing the library:

    javascript
    npm install lodash

4. A manual recursive copy (to understand the mechanics)

If you want to understand how it works, here's a basic implementation:

javascript
function deepClone(obj) { if (obj === null || typeof obj !== 'object') return obj; if (Array.isArray(obj)) { return obj.map(deepClone); } const clone = {}; for (const key in obj) { clone[key] = deepClone(obj[key]); } return clone; } const user = { name: 'Alice', address: { city: 'Kyiv' } }; const clone = deepClone(user); clone.address.city = 'Lviv'; console.log(user.address.city); // "Kyiv"

Works for plain objects and arrays, but not for Map, Set, Date, RegExp, etc. (for that you need Lodash or structuredClone).


Summary

MethodSupportCopies nested objectsPreserves types (Date, Map, Set)Copies functions
structuredClone()Modern browsers, Node 17+YesYesNo
JSON.parse(JSON.stringify())EverywhereYesNoNo
_.cloneDeep()Via the Lodash libraryYesYesNo
Recursive functionManual implementationYesNoNo

In one phrase:

For a reliable deep copy, use structuredClone(obj) if you need a built-in function, _.cloneDeep(obj) if the project is large and stability matters.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.