【JavaScript】---- JS原生的深拷贝API structuredClone 使用详解与注意事项

1. 什么是 structuredClone?

structuredClone 是 JavaScript 内置的深拷贝方法,基于结构化克隆算法,用于复制复杂对象(如包含嵌套对象、数组、Date、Map、Set 等类型的数据),并支持处理循环引用。它替代了传统的 JSON.parse(JSON.stringify()) 深拷贝方法,解决了后者无法复制特殊对象和丢失数据类型的问题。

2. 语法

scss 复制代码
structuredClone(value)
structuredClone(value, options)

3. 参数

  1. value: 被克隆的对象。可以是任何结构化克隆支持的类型
  2. 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 支持的数据类型

  1. 原始类型:string、number、boolean、null、undefined、BigInt;
  2. 对象类型:Object、Array、Date、RegExp、Map、Set、ArrayBuffer;
  3. 特殊类型:Error(部分场景)、Blob、ImageBitmap(浏览器环境);
  4. 循环引用:自动处理对象内部的循环引用。

6. structuredClone 无法克隆的类型

  1. 函数(Function)、DOM 节点;
  2. 对象原型链:克隆后的对象原型为 Object,而非原构造函数(如 class 实例会丢失方法);
  3. 部分特殊对象: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. 兼容性

注意

  1. 深拷贝大数据量或嵌套层级过深的对象时,可能产生性能损耗。
  2. 深拷贝方法对比:
场景 推荐方法 注意事项
简单对象深拷贝 structuredClone 避免用于含函数的对象。
保留原型链的深拷贝 手动实现或 lodash.cloneDeep 需处理循环引用。
兼容旧浏览器 JSON.parse(JSON.stringify()) 丢失特殊类型(如 Date、Map)。
相关推荐
一点七加一1 小时前
Harmony鸿蒙开发0基础入门到精通Day07--JavaScript篇
开发语言·javascript·ecmascript
美狐美颜sdk5 小时前
跨平台直播美颜sdk集成攻略:Android、iOS与Web的统一方案
android·前端·ios
Airser5 小时前
npm启动Taro框架报错
前端·npm·taro
Anlici6 小时前
连载小说大学生课设 需求&架构
前端·javascript·后端
i源7 小时前
Java语言处理Js文件内容格式化
java·javascript
2501_938769997 小时前
React Server Components 进阶:数据预取与缓存
前端·react.js·缓存
“负拾捌”8 小时前
基于NodeJs实现一个MCP客户端(会话模式和无会话模式)
javascript·ai·node.js·大模型·mcp
蒜香拿铁8 小时前
Angular【基础语法】
前端·javascript·angular.js
xiaoxiao无脸男8 小时前
纯css:一个好玩的按钮边框动态动画
前端·css·css3
rookie_fly8 小时前
基于Vue的数字输入框指令
前端·vue.js·设计模式