使用js实现深拷贝

使用js实现深拷贝
最新回答
|欧巴桑_

2026-10-23 06:06:31

在 JavaScript 中,深拷贝是指创建一个新对象,完全复制原始对象的所有属性和嵌套对象,确保新对象与原始对象完全独立。以下是几种实现深拷贝的方法及其详细说明:

1. 使用 JSON 方法(简单但有局限)const deepCopy = JSON.parse(JSON.stringify(obj));

特点:

  • 优点:简单易用,适用于大多数简单对象。
  • 缺点:

    无法处理函数、undefined、Symbol、循环引用。

    会丢失对象的原型链和特殊类型(如 Date、RegExp 会被转为字符串或空对象)。

示例:

const obj = { a: 1, b: { c: 2 } };const copy = JSON.parse(JSON.stringify(obj));copy.b.c = 3;console.log(obj.b.c); // 2(原对象未受影响)2. 递归实现深拷贝(推荐)

通过递归遍历对象属性,手动复制每一层数据:

function deepClone(obj, hash = new WeakMap()) { // 处理基本类型和 null/undefined if (obj === null || typeof obj !== 'object') return obj; // 处理循环引用 if (hash.has(obj)) return hash.get(obj); // 处理 Date 和 RegExp if (obj instanceof Date) return new Date(obj); if (obj instanceof RegExp) return new RegExp(obj); // 创建新对象或数组 const clone = Array.isArray(obj) ? [] : {}; hash.set(obj, clone); // 记录已拷贝对象 // 递归拷贝属性 for (const key in obj) { if (obj.hasOwnProperty(key)) { clone[key] = deepClone(obj[key], hash); } } return clone;}

特点:

  • 优点:

    支持循环引用(通过 WeakMap 记录已拷贝对象)。

    保留对象原型链和特殊类型(如 Date、RegExp)。

  • 缺点:

    代码较复杂,需处理多种边界情况。

示例:

const obj = { a: 1, b: { c: 2 } };const copy = deepClone(obj);copy.b.c = 3;console.log(obj.b.c); // 23. 使用第三方库
  • Lodash:提供成熟的 _.cloneDeep 方法。const _ = require('lodash');const copy = _.cloneDeep(obj);
  • 优点:性能优化且经过充分测试,适合生产环境。
4. 其他方法(不推荐)
  • Object.assign 或展开运算符 {...obj}:仅实现浅拷贝。
  • structuredClone(实验性 API):const copy = structuredClone(obj);

    支持大多数类型(包括 Date、RegExp),但无法拷贝函数和原型链。

关键注意事项
  1. 循环引用:递归实现需用 WeakMap 避免无限循环。
  2. 特殊类型:需单独处理 Date、RegExp、Map、Set 等。
  3. 性能:大数据量时,递归可能栈溢出,可改用循环+栈的迭代方式。
总结
  • 简单场景:用 JSON.parse(JSON.stringify())(但需注意类型丢失)。
  • 复杂需求:使用递归实现或 Lodash 的 _.cloneDeep。
  • 未来标准:关注 structuredClone 的兼容性。

通过合理选择方法,可以确保深拷贝的准确性和性能。