JavaScript 深拷贝与浅拷贝详解

前言

在 JavaScript 开发中,拷贝对象是一个非常常见的操作。

但很多时候你以为"复制成功了",其实只是复制了引用,这就会引发很多 Bug。

所以必须搞清楚:

  • 什么是浅拷贝
  • 什么是深拷贝
  • 常见实现方式有哪些

一、浅拷贝是什么?

浅拷贝只会复制对象的第一层属性。

如果属性值还是对象,那么复制的仍然是引用地址。

ini 复制代码
const obj1 = {
  name: 'Tom',
  info: {
    age: 18
  }
};

const obj2 = { ...obj1 };

obj2.info.age = 20;

console.log(obj1.info.age); // 20

说明obj1.infoobj2.info指向同一个对象。


二、常见浅拷贝方式

1)展开运算符

ini 复制代码
const obj2 = { ...obj1 };

2)Object.assign

ini 复制代码
const obj2 = Object.assign({}, obj1);

这两种都属于浅拷贝。


三、深拷贝是什么?

深拷贝会递归复制对象的每一层,生成完全独立的新对象。

ini 复制代码
const obj1 = {
  name: 'Tom',
  info: {
    age: 18
  }
};

const obj2 = JSON.parse(JSON.stringify(obj1));

obj2.info.age = 20;

console.log(obj1.info.age); // 18

四、JSON 深拷贝的问题

虽然:

javascript 复制代码
JSON.parse(JSON.stringify(obj))

很常见,但它有局限:

  • 不能拷贝函数

  • 不能拷贝 undefined

  • 不能拷贝Symbol

  • 不能处理循环引用

  • DateRegExp 会丢失信息


五、手写一个简单深拷贝

ini 复制代码
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  const result = Array.isArray(obj) ? [] : {};

  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      result[key] = deepClone(obj[key]);
    }
  }

  return result;
}

六、总结

浅拷贝和深拷贝最核心的区别是:

  • 浅拷贝:只拷贝第一层
  • 深拷贝:递归拷贝所有层级

实际开发中要根据场景选择,不要把浅拷贝误当成深拷贝。

相关推荐
Highcharts.js2 小时前
Highcharts React v4 迁移指南(上):核心变更解析与升级收益
前端·javascript·react.js·react·数据可视化·highcharts·v4迁移
菌菌的快乐生活2 小时前
在 WPS 中设置 “第一章”“第二章” 这类一级编号标题自动跳转至新页面
前端·javascript·wps
hh随便起个名2 小时前
useRef和useState对比
前端·javascript·react
吴声子夜歌3 小时前
JavaScript——对象
开发语言·javascript·ecmascript
不会写DN3 小时前
Js常用的字符串处理
开发语言·前端·javascript
晓13133 小时前
第三章 TypeScript 高级类型
前端·javascript·typescript
Sylus_sui3 小时前
鸿蒙音乐项目懒加载优化实战
javascript
SuperEugene4 小时前
Vue keep-alive 实战避坑:include/exclude + 路由 meta 标记,中后台路由缓存精准可控|状态管理与路由规范篇
开发语言·前端·javascript·vue.js·缓存·前端框架
被考核重击4 小时前
虚拟列表(动态高度,性能优化,骨架屏)
javascript·vue.js·性能优化·虚拟列表