structuredClone - 浏览器原生方法用于对象的深拷贝
深拷贝一般都需要我们自己写代码来实现,比如通过递归、JSON的stringify()和parse()、Object.assign()等,现在提出了structuredClone方法,它属于浏览器原生方式,直接用于对象的的深拷贝(deep clone)。
structuredClone api 目前已经成为了一个 html 规范中的标准提案,用它可以轻松实现一个深拷贝,并且也默认解决了循环引用等问题、支持了很多默认的数据类型。
并且,相比 JSON.parse() ,structuredClone API 的性能更好,特别是在处理一些更大复杂的对象的时候,所以我们可以用它来作为代码里深拷贝的默认方法啦,为了兼容性考虑,可以用 JSON.stringify 或者其他工具函数作为备用
不过,这个 API 也并不完美,它也有些缺点:
原型:无法拷贝对象的原型链。
函数:无法拷贝函数。
不可克隆:并没有支持所有类型的拷贝,比如 Error。
当然,大部分实际的需求场景中,我们没必要拷贝这些东西,估计这些也就只能出现在面试题里面了。
语法
structuredClone(value, { transfer })value:要克隆的对象。
transfer:值为数组,其数组value将被移动而不是克隆到返回的对象中(选填)。
代码示例
此函数可用于深度复制 JavaScript 值。它还支持循环引用,如下所示:
// 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 preservedtransfer参数
以下代码显示了如何克隆一个数组并将其底层资源转移到新对象。返回时,原件uInt8Array.buffer将被清除。
var uInt8Array = new Uint8Array(1024 * 1024 * 16); // 16MB
for (var i = 0; i < uInt8Array.length; ++i) {
uInt8Array[i] = i;
}
const transferred = structuredClone(uInt8Array, { transfer: [uInt8Array.buffer] }).
console.log(uInt8Array.byteLength); // 0您可以克隆任意数量的对象并传输这些对象的任何子集。例如,下面的代码arrayBuffer1将从传入的值传输,但不是arrayBuffer2.
const transferred = structuredClone(
{ x: { y: { z: arrayBuffer1, w: arrayBuffer2 } } },
{ transfer: [arrayBuffer1] });兼容性
目前,主流浏览器Safari已经在其94稳定版本支持了,Chrome和Safari将在最新版支持该方法,另外Node 17 和 Deno 1.14 也已经实现了这个 API,未来一定会成为一个被广泛使用的API的。

本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!