structuredClone() 是 JavaScript 中一个用于深拷贝对象的全局方法,从 ES2022(ECMAScript 2022) 开始正式引入,现代浏览器(Chrome 98+、Firefox 94+、Safari 15.4+)和 Node.js 17+ 已支持。
✅ 为什么需要 structuredClone?
在 JavaScript 中,对象是引用类型。使用 = 赋值或 Object.assign()、扩展运算符 ... 等方式只能实现浅拷贝,嵌套对象仍然共享引用。
传统深拷贝方法如 JSON.parse(JSON.stringify(obj)) 存在很多缺陷:
- 不能处理函数、
undefined、Symbol、Map、Set、Date、RegExp、循环引用等。 - 会丢失原型链和不可枚举属性。
- 性能差,且不安全(如
toJSON方法可能被篡改)。
structuredClone() 就是为了解决这些问题而设计的标准化深拷贝方案。
🧩 语法
const cloned = structuredClone(value, options);参数:
value:要克隆的值(对象、数组、Map、Set、Date、RegExp、Blob、File、ArrayBuffer 等)options(可选):transfer: 数组,包含可转移的对象(如ArrayBuffer),转移后原对象不可用。
🎯 支持的数据类型
structuredClone() 支持克隆以下类型:
- 所有原始类型(
string,number,boolean,null,undefined,BigInt,Symbol) DateRegExpArray,ObjectMap,SetArrayBuffer,TypedArray,DataViewBlob,File,FileListImageData- 循环引用对象(自动处理)
- 自定义类实例(仅拷贝可枚举自有属性,不拷贝原型方法)
⚠️ 注意:函数、DOM 节点、Error对象、WeakMap/WeakSet等不支持克隆,会抛出错误。
📌 示例
1. 基础对象深拷贝
const obj = {
name: "Alice",
hobbies: ["reading", "coding"],
birth: new Date(),
meta: {
id: 123,
tags: new Set(["js", "es6"])
}
};
const clone = structuredClone(obj);
console.log(clone.meta.tags === obj.meta.tags); // false — 深拷贝成功!2. 处理循环引用
const obj = { a: 1 };
obj.self = obj; // 循环引用
const clone = structuredClone(obj);
console.log(clone.self === clone); // true — 正确处理循环引用3. 克隆 Map/Set
const map = new Map([["key", { nested: "value" }]]);
const clonedMap = structuredClone(map);
console.log(clonedMap.get("key") === map.get("key")); // false — 深拷贝4. 使用 transfer 选项(转移 ArrayBuffer)
const buffer = new ArrayBuffer(16);
const view = new Uint8Array(buffer);
view[0] = 42;
const clone = structuredClone(buffer, { transfer: [buffer] });
console.log(buffer.byteLength); // 0 — 原 buffer 被“转移”,不可用
console.log(clone.byteLength); // 16 — 新 buffer 可用⚠️ 限制与注意事项
- ❌ 不支持函数、类方法、DOM 节点、Error 对象、WeakMap/WeakSet
- ❌ 不克隆原型链或不可枚举属性
- ❌ 不克隆带有
[[Call]]的对象(如函数) - ✅ 支持循环引用
- ✅ 性能优于
JSON.parse(JSON.stringify()) - ✅ 安全,不会执行
toJSON或 getter
🆚 与其他深拷贝方式对比
| 方法 | 支持函数 | 支持循环引用 | 支持 Map/Set | 安全性 | 性能 |
|---|---|---|---|---|---|
structuredClone() | ❌ | ✅ | ✅ | ✅ | ✅ |
JSON.parse(JSON.stringify()) | ❌ | ❌ | ❌ | ❌ | ❌ |
Lodash _.cloneDeep() | ✅ | ✅ | ✅ | ✅ | ⚠️ 中等 |
| 自定义递归深拷贝 | ✅ | ✅(需手动) | ✅(需手动) | ✅ | ❌ |
🧪 浏览器兼容性
推荐使用前进行特性检测:
if (typeof structuredClone === "function") {
// 支持
} else {
// 降级方案,如使用 Lodash 或 polyfill
}✅ 总结
structuredClone() 是现代 JavaScript 中最推荐的深拷贝方法,它:
- 标准化、安全、高效
- 支持复杂数据结构和循环引用
- 无需引入第三方库
适用于大多数数据克隆场景(除函数和 DOM 外)。
📌 推荐使用场景:
- 状态管理(如 Redux/Vuex 中避免直接修改 state)
- 数据快照、撤销/重做功能
- Worker 通信前的数据复制
- 避免引用污染的配置对象拷贝
✅ 现在就开始用 structuredClone() 吧,告别 JSON.parse(JSON.stringify()) 的坑!
相关推荐
- 深入解析navigator.clipboard:现代浏览器剪贴板操作指南 2025-07-30
评论0
暂时没有评论