导读:本期聚焦于小伙伴创作的《JavaScript中深浅拷贝的实现原理是什么?对象操作该怎么选?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript中深浅拷贝的实现原理是什么?对象操作该怎么选?》有用,将其分享出去将是对创作者最好的鼓励。

在JavaScript中,对象、数组等引用类型的变量存储的是内存地址的引用,直接通过赋值操作符得到的只是地址的复制,修改新变量会同步影响原变量。深浅拷贝就是为了解决引用类型复制时的数据隔离问题而出现的两种方案,二者的核心差异在于是否复制引用类型内部的嵌套引用类型数据。

JavaScript中深浅拷贝的实现原理是什么?对象操作该怎么选?

浅拷贝的实现原理

浅拷贝只会复制目标对象的第一层属性,如果属性是基本类型,就直接复制值;如果属性是引用类型,就复制其引用地址,因此修改新对象的引用类型属性仍然会影响原对象。

常见浅拷贝实现方式

1. 使用Object.assign方法

Object.assign是ES6提供的对象合并方法,当只传入一个目标对象时,会返回该对象的浅拷贝结果。

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

// 浅拷贝
const shallowCopyObj = Object.assign({}, originObj);

// 修改基本类型属性,不影响原对象
shallowCopyObj.name = 'newTest';
console.log(originObj.name); // 输出test

// 修改引用类型属性,会影响原对象
shallowCopyObj.info.age = 25;
console.log(originObj.info.age); // 输出25

2. 扩展运算符实现浅拷贝

扩展运算符...也可以快速实现对象的浅拷贝,原理和Object.assign一致。

const originObj = {
  name: 'test',
  list: [1, 2, 3]
};

// 扩展运算符浅拷贝
const shallowCopyObj = { ...originObj };

shallowCopyObj.list.push(4);
console.log(originObj.list); // 输出[1,2,3,4]

3. 手写浅拷贝函数

手写浅拷贝的核心逻辑是遍历原对象的所有可枚举属性,将其赋值到新对象中。

function shallowClone(target) {
  // 只处理对象类型
  if (typeof target !== 'object' || target === null) {
    return target;
  }
  // 根据原对象类型初始化新对象
  const result = Array.isArray(target) ? [] : {};
  // 遍历属性赋值
  for (let key in target) {
    // 只复制自身属性,不复制原型链上的属性
    if (target.hasOwnProperty(key)) {
      result[key] = target[key];
    }
  }
  return result;
}

// 测试
const origin = { a: 1, b: { c: 2 } };
const copy = shallowClone(origin);
copy.b.c = 3;
console.log(origin.b.c); // 输出3

深拷贝的实现原理

深拷贝会递归复制目标对象的所有层级属性,无论是基本类型还是引用类型,都会复制出一份完全独立的新数据,修改新对象不会影响原对象。

常见深拷贝实现方式

1. JSON序列化反序列化法

利用JSON.stringify将对象转为JSON字符串,再用JSON.parse将字符串转回对象,这个过程会重新构建所有层级的数据,实现深拷贝。

const originObj = {
  name: 'test',
  info: {
    age: 20,
    hobby: ['reading', 'coding']
  },
  date: new Date(),
  func: function() { console.log('test'); }
};

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

deepCopyObj.info.age = 25;
console.log(originObj.info.age); // 输出20

// 注意:该方法有局限性,会丢失函数、undefined、Date等特殊类型
console.log(deepCopyObj.date); // 输出字符串格式的日期,不是Date对象
console.log(deepCopyObj.func); // 输出undefined

这种方式的局限性很明显:无法复制函数、undefined、Symbol类型,Date对象会变成字符串,RegExp、Error等对象会丢失原有特性,也不能处理循环引用的情况。

2. 手写递归深拷贝函数

递归深拷贝的核心是遍历对象的所有属性,如果遇到引用类型属性,就递归调用拷贝函数,直到所有属性都是基本类型为止。

function deepClone(target, map = new WeakMap()) {
  // 处理基本类型和null
  if (typeof target !== 'object' || target === null) {
    return target;
  }
  // 处理循环引用,如果已经拷贝过该对象,直接返回缓存的结果
  if (map.has(target)) {
    return map.get(target);
  }
  // 处理特殊对象类型
  if (target instanceof Date) {
    return new Date(target);
  }
  if (target instanceof RegExp) {
    return new RegExp(target.source, target.flags);
  }
  // 初始化结果对象,保持和原对象一致的类型
  const result = Array.isArray(target) ? [] : {};
  // 将当前对象存入缓存
  map.set(target, result);
  // 遍历所有自有属性(包括Symbol属性)
  Reflect.ownKeys(target).forEach(key => {
    // 递归拷贝属性值
    result[key] = deepClone(target[key], map);
  });
  return result;
}

// 测试
const origin = {
  name: 'test',
  info: { age: 20 },
  date: new Date(),
  func: function() { return 1; },
  sym: Symbol('test')
};
// 添加循环引用
origin.self = origin;

const copy = deepClone(origin);
copy.info.age = 25;
console.log(origin.info.age); // 输出20
console.log(copy.date instanceof Date); // 输出true
console.log(copy.func()); // 输出1
console.log(copy.self === copy); // 输出true,循环引用处理正常

深浅拷贝的对比与选择

我们可以通过下表快速对比两种拷贝方式的差异:

对比维度浅拷贝深拷贝
复制层级仅第一层属性所有层级属性
数据独立性嵌套引用类型仍共享完全独立
性能消耗低,速度快高,速度慢
适用场景对象只有一层属性,或明确不需要隔离嵌套引用类型需要完全隔离原对象和新对象,嵌套层级多或不确定

在实际开发中,如果对象结构简单,只有一层基本类型属性,优先选择浅拷贝,性能更好;如果对象包含多层嵌套的引用类型,或者需要避免修改新对象影响原数据,就选择深拷贝。如果深拷贝的对象不包含特殊类型,也可以使用JSON序列化方法快速实现,否则建议使用递归深拷贝函数。

注意事项

  • 基本类型(number、string、boolean、null、undefined、Symbol)不存在拷贝问题,赋值就是值的复制。
  • 浅拷贝的实现方式还有数组的sliceconcat方法,原理和对象浅拷贝一致。
  • 手写深拷贝函数时,一定要处理循环引用的情况,否则会出现栈溢出错误。
  • 如果项目中频繁使用深拷贝,可以考虑引入成熟的工具库如lodash的cloneDeep方法,避免重复造轮子。

JavaScript深浅拷贝对象操作引用类型修改时间:2026-06-11 18:33:22

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