A shallow copy makes a new top-level object, but nested objects are still shared. A deep copy copies every level, so nothing is shared.
Shallow copy:
- Spread (
{ ...obj },[...arr]),Object.assign,Array.fromandsliceare all shallow. - If you change a nested property through the copy, the original changes too.
Deep copy with structuredClone(obj): this is the modern built-in.
- It handles nested objects, cyclic references (objects that point back to themselves),
Date,Map,Set, typed arrays and more. - It throws an error on functions and DOM nodes.
- It does not keep class prototypes, getters or symbol keys.
Pitfalls of JSON.parse(JSON.stringify(obj)):
- It drops
undefined, functions and symbol values. - It turns
Dateinto a string. - It turns
NaNandInfinityintonull. - It turns
MapandSetinto{}. - It throws on cycles and on
BigInt. - It loses prototypes.
- A shallow copy makes a new top level, but nested objects are still shared.
- Spread,
Object.assignandslicemake shallow copies. structuredClonemakes deep copies and supports cycles,Date,MapandSet.structuredClonethrows on functions and loses prototypes.- The JSON round-trip loses
undefinedand functions, turns dates into strings, and throws on cycles.
Read more