structuredClone() 全局函数
注意:此功能在Web Workers 中可用。
全局structuredClone()
方法使用结构化克隆算法创建给定值的深拷贝。
该方法还允许将原始值中的可传输对象传输到新对象,而不是克隆到新对象。传输的对象与原始对象分离并附加到新对象;它们在原始对象中不再可访问。
语法
js
structuredClone(value)
structuredClone(value, options)
参数
返回值
返回值是原始value
的深拷贝。
异常
DataCloneError
DOMException
-
如果输入值的任何部分不可序列化,则抛出此异常。
描述
此函数可用于深拷贝 JavaScript 值。它还支持循环引用,如下所示
js
// Create an object with a value and a circular reference to itself.
const original = { name: "MDN" };
original.itself = original;
// Clone it
const clone = structuredClone(original);
console.assert(clone !== original); // the objects are not the same (not same identity)
console.assert(clone.name === "MDN"); // they do have the same values
console.assert(clone.itself === clone); // and the circular reference is preserved
传输值
可以使用options
参数的transfer
属性,将可传输对象(仅)传输到克隆的对象,而不是复制到克隆的对象。传输会使原始对象无法使用。
注意:在异步验证缓冲区中的一些数据然后再保存它时,这可能很有用。为了避免在保存数据之前修改缓冲区,您可以克隆缓冲区并验证该数据。如果您还传输数据,则任何尝试修改原始缓冲区的操作都将失败,从而防止意外误用。
以下代码演示了如何克隆数组并将它的底层资源传输到新对象。返回后,原始uInt8Array.buffer
将被清除。
js
// 16MB = 1024 * 1024 * 16
const uInt8Array = Uint8Array.from({ length: 1024 * 1024 * 16 }, (v, i) => i);
const transferred = structuredClone(uInt8Array, {
transfer: [uInt8Array.buffer],
});
console.log(uInt8Array.byteLength); // 0
您可以克隆任意数量的对象并传输这些对象的任意子集。例如,下面的代码将从传入的值中传输arrayBuffer1
,但不传输arrayBuffer2
。
js
const transferred = structuredClone(
{ x: { y: { z: arrayBuffer1, w: arrayBuffer2 } } },
{ transfer: [arrayBuffer1] },
);
示例
克隆对象
在此示例中,我们克隆一个包含一个成员(一个数组)的对象。克隆后,对每个对象所做的更改不会影响另一个对象。
js
const mushrooms1 = {
amanita: ["muscaria", "virosa"],
};
const mushrooms2 = structuredClone(mushrooms1);
mushrooms2.amanita.push("pantherina");
mushrooms1.amanita.pop();
console.log(mushrooms2.amanita); // ["muscaria", "virosa", "pantherina"]
console.log(mushrooms1.amanita); // ["muscaria"]
传输对象
在此示例中,我们创建一个ArrayBuffer
,然后克隆它所属的对象,并传输该缓冲区。我们可以在克隆的对象中使用该缓冲区,但是如果我们尝试使用原始缓冲区,我们将获得异常。
js
// Create an ArrayBuffer with a size in bytes
const buffer1 = new ArrayBuffer(16);
const object1 = {
buffer: buffer1,
};
// Clone the object containing the buffer, and transfer it
const object2 = structuredClone(object1, { transfer: [buffer1] });
// Create an array from the cloned buffer
const int32View2 = new Int32Array(object2.buffer);
int32View2[0] = 42;
console.log(int32View2[0]);
// Creating an array from the original buffer throws a TypeError
const int32View1 = new Int32Array(object1.buffer);
规范
规范 |
---|
HTML 标准 # dom-structuredclone |
浏览器兼容性
BCD 表仅在启用 JavaScript 的浏览器中加载。