structuredClone
structuredClone() creates a deep copy of a value, preserving types
and references within the value: nested objects stay nested, two
references to the same object stay shared in the clone, cycles are
handled, and built-in types (Date, RegExp, Map, Set, ArrayBuffer,
typed arrays, and more) clone as their own type instead of degrading to
plain objects. Unlike JSON.parse(JSON.stringify(value)), nothing is
flattened to strings and cycles do not throw.
structuredClone(value)returns a deep clone.structuredClone(value, { transfer })moves ownership of supported binary objects (ArrayBuffers) to the clone instead of copying their bytes.- Non-cloneable values — functions, DOM/host objects, symbols as
values — throw a
DataCloneError.
Usage#
const original = {
created: new Date(),
tags: new Set(["a", "b"]),
meta: new Map([["retries", 3]]),
};
const copy = structuredClone(original);
copy.created instanceof Date; // true
copy.tags instanceof Set; // true
copy.meta === original.meta; // false
Shared references and cycles survive:
const node = { name: "root" };
node.self = node;
const clone = structuredClone(node);
clone.self === clone; // true (cycle preserved in the clone)
clone.self !== node; // true (it is a real copy)
structuredClone(() => {}); // throws DataCloneError
Supported types include objects, arrays, Date, Map, Set,
RegExp, ArrayBuffer and typed arrays, Blob, and File.
Differences from the standard#
Errorobjects are not cloneable (cloning one throws), while the standard supports cloningErrors with their message and stack.CryptoKeyobjects are not cloneable. Cloning aCryptoKey, or an object containing one, throwsDataCloneError.- The
{ transfer }option is best avoided: platform binary types can only be transferred in limited ways, so behavior may differ from engines with native implementations. PlainArrayBuffertransfer works.