1. 什么是 structuredClone?
structuredClone 是 JavaScript 内置的深拷贝方法,基于结构化克隆算法,用于复制复杂对象(如包含嵌套对象、数组、Date、Map、Set 等类型的数据),并支持处理循环引用。它替代了传统的 JSON.parse(JSON.stringify()) 深拷贝方法,解决了后者无法复制特殊对象和丢失数据类型的问题。
2. 语法
scss
structuredClone(value)
structuredClone(value, options)
3. 参数
- value: 被克隆的对象。可以是任何结构化克隆支持的类型。
- options:一个具有以下属性的对象: 2.1 transfer:一个可转移对象的数组,里面的对象将被移动而不是克隆到返回的对象上。
4. 基础实例
4.1 实例代码
javascript
const original = {
date: new Date(),
map: new Map([['key', 'value']]),
array: [1, { name: 'test' }]
};
// 深拷贝对象
const cloned = structuredClone(original);
console.log(cloned.date instanceof Date); // true(原数据类型保留)
console.log(cloned.map instanceof Map); // true
console.log(cloned.array[1] === original.array[1]); // false(深拷贝生效)
4.2 执行结果
5. structuredClone 支持的数据类型
- 原始类型:string、number、boolean、null、undefined、BigInt;
- 对象类型:Object、Array、Date、RegExp、Map、Set、ArrayBuffer;
- 特殊类型:Error(部分场景)、Blob、ImageBitmap(浏览器环境);
- 循环引用:自动处理对象内部的循环引用。
6. structuredClone 无法克隆的类型
- 函数(Function)、DOM 节点;
- 对象原型链:克隆后的对象原型为 Object,而非原构造函数(如 class 实例会丢失方法);
- 部分特殊对象:Promise、WeakMap、Proxy。
7. 函数测试
7.1 测试代码
bash
let obj = { test: () => { } }
let clone = structuredClone(obj)
7.2 测试结果
8. DOM 对象测试
8.1 测试代码
ini
let dom1 = { el: document.body }
let clone1 = structuredClone(dom1)
8.2 测试结果
9. 原型链
9.1 测试代码
javascript
class User { greet() {} }
const user = new User();
const clonedUser = structuredClone(user);
console.log(clonedUser instanceof User);
9.2 测试结果
10. 部分特殊对象测试
10.1 测试 Promise 代码
javascript
const originalPromise = new Promise((resolve) => resolve(42));
try {
const clonedPromise = structuredClone(originalPromise);
} catch (error) {
console.error("克隆 Promise 失败:", error.message);
}
10.2 测试 Promise 结果
10.3 测试 WeakMap 代码
vbnet
const originalWeakMap = new WeakMap();
const key = {};
originalWeakMap.set(key, "value");
try {
const clonedWeakMap = structuredClone(originalWeakMap);
} catch (error) {
console.error("克隆 WeakMap 失败:", error.message);
}
10.4 测试 WeakMap 结果
10.5 测试 Proxy 代码
ini
const target = { value: 100 };
const originalProxy = new Proxy(target, {
get: (obj, prop) => obj[prop] * 2,
});
try {
const clonedProxy = structuredClone(originalProxy);
} catch (error) {
console.error("克隆 Proxy 失败:", error.message);
}
10.6 测试 Promise 结果
11. 兼容性
注意
- 深拷贝大数据量或嵌套层级过深的对象时,可能产生性能损耗。
- 深拷贝方法对比:
场景 | 推荐方法 | 注意事项 |
---|---|---|
简单对象深拷贝 | structuredClone | 避免用于含函数的对象。 |
保留原型链的深拷贝 | 手动实现或 lodash.cloneDeep | 需处理循环引用。 |
兼容旧浏览器 | JSON.parse(JSON.stringify()) | 丢失特殊类型(如 Date、Map)。 |