structuredClone(): The Easiest Way to Copy Objects in JavaScript

Cloning objects is a regular programming task for storing or passing data. Until recently, developers have had to rely on third-party libraries to perform this operation because of advanced needs like deep-copying or keeping circular references.

Fortunately, that’s no longer necessary, thanks to the new built-in method called structuredClone(). This feature provides an easy and efficient way to deep-clone objects without external libraries. It works in most modern browsers (as of 2022) and Node.js (as of v17).

In this article, we will explore the benefits and downsides of using structuredClone() function to clone objects in JavaScript.

How to use structuredClone()

structuredClone() works very intuitively; pass the original object to the function, and it will return a deep copy with a different reference and object property references.

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

Unlike the well-known JSON stringify/parse “hack”, structuredClone() lets you clone circular references.

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

Advantages of structuredClone()

So, what makes structuredClone() so great? Well, we’ve been saying it right from the intro; it allows you to make deep copies of objects without difficulty. You don’t need to install any third-party libraries or use JSON.stringify/parse to do so.

With structuredClone(), you can clone objects that have circular references, which is something that’s not possible with the JSON approach. You can clone complex objects and data structures with ease.

structuredClone() can deep copy for as many levels as you need; it creates a completely new copy of the original object with no shared references or properties. This means that any changes made to the cloned object won’t affect the original, and vice versa.

Limitations of structuredClone()

While structuredClone() is a powerful function for cloning objects and data structures, it does have some limitations that are worth noting.

Can’t clone functions or methods

Yes, structuredClone() cannot clone functions or methods. This is because of the structured clone algorithm that the function uses. The algorithm can’t duplicate function objects and throws a DataCloneError exception.

JavaScript
function func() {} // Error: func could not be cloned const funcClone = structuredClone(func);
JavaScript
const car = { make: 'BMW', move() { console.log('vroom vroom..'); }, }; car.basedOn = car; // ❌ Error: move() could not be cloned const cloned = structuredClone(car);

As you can see from the above example, trying to use structuredClone() on a function or an object with a method will cause an error.

Can’t clone DOM elements

Similarly, the structured clone algorithm used by structuredClone() can’t clone DOM elements. Passing an HTMLElement object to structuredClone() will cause an error like the one above.

JavaScript
const input = document.querySelector('#text-field'); // ❌ Failed: HTMLInputElement object could not be cloned. const clone = structuredClone(input);

Doesn’t preserve RegExp lastIndex property

When you clone a RegExp object with structuredClone() the lastIndex property of a RegExp is not preserved in the clone:

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 of structuredClone()

  • It doesn’t preserve property metadata or descriptors. For example, If a property descriptor marks an object as readonly, the clone of the object will be read/write by default.
  • It doesn’t preserve non-enumerable properties in the clone.

These limitations shouldn’t be much of a drawback for most use cases, but still, it’s important to be aware of them to avoid unexpected behavior when using the function.

Transfer value with structuredClone()

When you clone an object, you can transfer particular objects instead of making copies by using the transfer property in the second options parameter that structuredClone() has. This means you can move objects between the original and cloned objects without creating duplicates. The original object can’t be used after the transfer.

Let’s say you have some data in a buffer that you need to validate before saving. By cloning the buffer and validating the cloned data instead, you can avoid any unwanted changes to the original buffer. Plus, if you transfer the validated data back to the original buffer, it will become immutable, and any accidental attempts to change it will be blocked. This can give you extra peace of mind when working with important data.

Let’s look at an example:

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

In this example, we created a UInt8Array buffer and fill it with data. Then, we clone it using structuredClone() and transfer the original buffer to the cloned object. This makes the original array unusable, ensuring it will be kept from being accidentally modified.

Key takeaways

structuredClone() is a useful built-in feature in JavaScript for creating deep copies of objects without external libraries. It has some limitations, like not being able to clone functions, methods, or DOM elements and not preserving some type of properties in the clone. You can use the transfer option to move objects between the original and cloned objects without creating duplicates, which can be helpful for validating data or ensuring immutability. Overall, structuredClone() is a valuable addition to a developer’s toolkit and makes object cloning in JavaScript easier than ever.



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 *