structuredClone(): The easiest way to deep copy objects in JavaScript

Deep copying is a regular programming task for passing or storing data.

  • Shallow copy: Only copies the first level of the object
  • Deep copy: Copies all levels of the object
JavaScript
const obj = { name: 'Tari', friends: [{ name: 'Messi'}]}; const shallowCopy = { ...obj }; const deepCopy = dCopy(obj); console.log(obj.friends === shallowCopy.friends); // ❌ true console.log(obj.friends === deepCopy.friends); // ✅ false

But all this while we’ve never had a built-in way to perfectly deep copy objects and it’s been a pain.

We always had to lean on third-party libraries for deep copying and keeping circular references.

All that changes now with the new structuredClone() — an easy and efficient way to deep copy any object.

JavaScript
const obj = { name: 'Tari', friends: [{ name: 'Messi' }] }; const clonedObj = structuredClone(obj); console.log(obj.name === clonedObj); // false console.log(obj.friends === clonedObj.friends); // false

Cloning circular references with ease:

JavaScript
const car = { make: 'Toyota', }; // 👉 Circular reference car.basedOn = car; const cloned = structuredClone(car); console.log(car.basedOn === cloned.basedOn); // false // 👇 Circular reference is cloned console.log(car === car.basedOn); // true

Something you could never do with the JSON stringify/parse hack:

Go as deep as you want:

JavaScript
// ↘️ const obj = { a: { b: { c: { d: { e: 'Coding Beauty', }, }, }, }, }; const clone = structuredClone(obj); console.log(clone.a.b.c.d === obj.a.b.c.d); // ✅ false console.log(clone.a.b.c.d.e); // Coding Beauty

Limitations you should know

structuredClone() is very powerful but it has important weaknesses you should know:

Can’t clone functions or methods

Because of the special algorithm it uses.

Can’t clone DOM elements

Doesn’t preserve RegExp lastIndex property

I mean, no one’s cloning regexes but it’s one to note:

JavaScript
const regex = /beauty/g; const str = 'Coding Beauty: JS problems are solved at Coding Beauty'; console.log(regex.index); console.log(regex.lastIndex); // 7 const regexClone = structuredClone(regex); console.log(regexClone.lastIndex); // 0

Other limitations

Important to be aware of them to avoid unexpected behavior when using the function.

Clone some, move

This is a more sophisticated one.

You transfer inner objects from source to clone instead of copying.

Which means there’s nothing left in source to change:

JavaScript
const uInt8Array = Uint8Array.from({ length: 1024 * 1024 * 16 }, (v, i) => i); const transferred = structuredClone(uInt8Array, { transfer: [uInt8Array.buffer], }); console.log(uInt8Array.byteLength); // 0

Overall structuredClone() is a valuable addition to a developer’s toolkit and makes object cloning easier than ever in JavaScript



Every Crazy Thing JavaScript Does

A captivating guide to the subtle caveats and lesser-known parts of JavaScript.

Every Crazy Thing JavaScript Does

Sign up and receive a free copy immediately.

Leave a Comment

Your email address will not be published. Required fields are marked *