Shallow vs Deep Copy
The problem - objects are reference types
js
const original = { name: 'Alice', address: { city: 'NYC' } };
const ref = original;
ref.name = 'Bob';
console.log(original.name); // 'Bob' - same object!Shallow copy - copies only the top level
js
const shallow1 = { ...original };
const shallow2 = Object.assign({}, original);
shallow1.name = 'Bob'; // ok - doesn't affect original
shallow1.address.city = 'LA'; // mutates original.address too!
// address is still a reference to the same objectDeep copy - copies everything recursively
structuredClone (modern, recommended)
js
const deep = structuredClone(original);
deep.address.city = 'LA'; // original.address.city is still 'NYC'JSON trick (limited)
js
const deep = JSON.parse(JSON.stringify(original));
// loses: undefined, functions, Date objects, Map, Set, circular refslodash cloneDeep
js
import { cloneDeep } from 'lodash';
const deep = cloneDeep(original);Comparison
| Method | Type | Handles Date/Map/Set | Circular refs |
|---|---|---|---|
{ ...obj } | Shallow | - | - |
Object.assign | Shallow | - | - |
structuredClone | Deep | Yes | Yes |
JSON trick | Deep | No | No |
lodash.cloneDeep | Deep | Yes | Yes |
structuredCloneis the right default for deep copying in modern JavaScript - it's native and handles edge cases well.
updated
did you know it?