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

Last updated on June 01, 2024
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
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.

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:

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:

// ↘️
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:

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:

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

Coding Beauty Assistant logo

Try Coding Beauty AI Assistant for VS Code

Meet the new intelligent assistant: tailored to optimize your work efficiency with lightning-fast code completions, intuitive AI chat + web search, reliable human expert help, and more.

See also