如何深拷贝对象?javascript中有哪些方法

来源:站长工具作者:厦门程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《如何深拷贝对象?javascript中有哪些方法》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何深拷贝对象?javascript中有哪些方法》有用,将其分享出去将是对创作者最好的鼓励。

在javascript中,对象属于引用类型,直接赋值只会复制对象的引用地址,修改新对象会影响原对象,这种拷贝方式属于浅拷贝。深拷贝则是创建一个全新的对象,完全复制原对象的所有层级属性,新对象和原对象互不影响。下面介绍几种javascript中实现深拷贝的常用方法。

如何深拷贝对象?javascript中有哪些方法

使用JSON方法实现深拷贝

JSON.parse和JSON.stringify组合是最简单的深拷贝实现方式,原理是将对象转为JSON字符串,再将字符串转回对象,从而切断引用关联。

// 原对象
const originObj = {
  name: 'test',
  age: 20,
  hobbies: ['reading', 'coding'],
  info: {
    city: 'Beijing'
  }
};

// 使用JSON方法深拷贝
const copyObj = JSON.parse(JSON.stringify(originObj));

// 修改拷贝后的对象
copyObj.age = 25;
copyObj.hobbies.push('swimming');
copyObj.info.city = 'Shanghai';

console.log(originObj.age); // 输出20,原对象未受影响
console.log(originObj.hobbies); // 输出["reading", "coding"],原对象未受影响
console.log(originObj.info.city); // 输出Beijing,原对象未受影响

这种方法的优点是代码简洁,不需要额外逻辑。但存在明显限制:无法拷贝函数、undefined、Symbol类型的值,Date对象会被转为字符串,RegExp、Error对象拷贝后会变成空对象,也不能处理对象循环引用的情况,遇到循环引用会直接报错。

递归遍历实现通用深拷贝

通过递归遍历对象的所有属性,逐层复制属性值,可以实现一个支持更多类型的深拷贝函数,还能处理循环引用问题。

// 深拷贝函数,支持处理循环引用
function deepClone(target, map = new WeakMap()) {
  // 处理基本类型和函数,直接返回
  if (typeof target !== 'object' || target === null) {
    return target;
  }

  // 处理循环引用,如果已经拷贝过该对象,直接返回拷贝后的对象
  if (map.has(target)) {
    return map.get(target);
  }

  // 处理数组和对象
  const result = Array.isArray(target) ? [] : {};

  // 将当前对象和拷贝后的对象存入map
  map.set(target, result);

  // 遍历对象自身可枚举属性
  for (const key in target) {
    if (target.hasOwnProperty(key)) {
      result[key] = deepClone(target[key], map);
    }
  }

  return result;
}

// 测试循环引用场景
const obj1 = { a: 1 };
obj1.self = obj1; // 对象引用自身,形成循环引用

const copyObj1 = deepClone(obj1);
console.log(copyObj1.self === copyObj1); // 输出true,循环引用被正确处理
console.log(copyObj1.a); // 输出1

这个递归方法可以处理大部分常见的数据类型,也能解决循环引用问题。但如果是特殊的内置对象比如Map、Set、Date、RegExp等,还需要额外添加对应的类型判断和处理逻辑,才能完整支持所有对象的深拷贝。

使用第三方库实现深拷贝

实际开发中如果需要稳定可靠的深拷贝能力,也可以直接使用成熟的第三方库,比如lodash的cloneDeep方法,它已经处理了各种边界情况和特殊类型的拷贝问题。

// 假设已经引入lodash库,使用cloneDeep方法
const _ = require('lodash');

const originObj = {
  name: 'demo',
  date: new Date(),
  fn: function() { console.log('test'); },
  map: new Map([['key1', 'value1']])
};

const copyObj = _.cloneDeep(originObj);
console.log(copyObj.date instanceof Date); // 输出true,Date对象被正确拷贝
console.log(copyObj.map.get('key1')); // 输出value1,Map对象被正确拷贝
copyObj.fn(); // 输出test,函数被正确拷贝

lodash的cloneDeep方法经过了大量场景的测试,稳定性更好,适合在项目中对拷贝可靠性要求较高的场景使用,缺点是会增加项目的依赖体积,如果是轻量场景可以自行实现简单的深拷贝逻辑。

不同深拷贝方法的适用场景

可以根据实际需求选择对应的深拷贝方案:

  • 如果拷贝的对象只包含基本类型、普通数组和普通对象,没有特殊类型和循环引用,优先使用JSON方法,代码最简单
  • 如果需要处理更多数据类型和循环引用,且不想引入第三方依赖,可以实现递归深拷贝函数,按需扩展特殊类型的处理逻辑
  • 如果项目本身已经使用了lodash等工具库,或者需要拷贝的对象包含复杂的内置对象类型,直接使用成熟的第三方深拷贝方法更稳妥

javascript深拷贝对象拷贝JSON_parse递归拷贝修改时间:2026-07-05 06:27:21

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。