「一文看懂 JS 深浅拷贝,彻底告别面试踩坑!」

在 JavaScript 开发中,深浅拷贝是一个绕不开的话题。无论是日常开发还是面试,拷贝对象的方式和原理都经常被问到。本文将用最简明的语言,结合实例,帮你彻底搞懂深浅拷贝的核心概念和常见实现方式,助你轻松应对各种场景!


一、什么是拷贝?为什么要拷贝?

拷贝,就是复制一个对象,让新对象和原对象"长得一模一样"。

但"复制"分为两种:浅拷贝和深拷贝。

  • 浅拷贝:只复制第一层属性,如果属性是引用类型(如对象、数组),复制的是"引用地址"。
  • 深拷贝:递归复制所有层级,嵌套对象也会被完整复制,新旧对象互不影响。

为什么要拷贝呢?

在 JS 中,为了避免直接修改原数据带来的副作用。这时候我们就需要复制这个对象,来操作复制的对象


二、JS 中的数据类型

理解拷贝,先要知道 JS 的数据类型:

  • 基本类型:number、string、boolean、null、undefined、symbol、bigint(存储在栈内存)
  • 引用类型:object、array、function、date、regexp 等(存储在堆内存)

基本类型直接存值,引用类型存的是"地址"。


三、浅拷贝:复制表面,引用共享

1. 常见实现方式

  • Object.assign({}, obj)
  • 数组解构 [...arr]
  • arr.slice()
  • [].concat(arr)
  • Object.create(obj)

2. 例子说明

假设有如下对象:

js 复制代码
const obj1 = {
  name: "小华",
  info: { age: 18 }
};
const obj2 = Object.assign({}, obj1);
obj2.name = "小鱼";
obj2.info.age = 20;
console.log(obj1); // { name: "小华", info: { age: 20 } }

解释
name 是基本类型,修改 obj2.name 不影响 obj1
info 是对象,浅拷贝只复制了引用,obj2.info.age 改变会影响 obj1.info.age

3. 适用场景

  • 只需要复制一层属性
  • 不关心嵌套对象是否联动

四、深拷贝:彻底分离,互不影响

1. 常见实现方式

  • JSON.parse(JSON.stringify(obj))
    简单粗暴,但有缺陷:不能识别 bigin(会报错),不能拷贝 functionsymbolundefined,也无法处理循环引用。
  • structuredClone(obj)
    新标准,支持更多类型,但兼容性有限。
  • 手写递归深拷贝(见下文)

2. 例子说明(JSON.parse(JSON.stringify(obj)))

js 复制代码
const obj1 = {
  name: "小华",
  info: { age: 18 }
};
const obj2 = JSON.parse(JSON.stringify(obj1));
obj2.info.age = 20;
console.log(obj1); // 

解释
obj2 完全独立,修改嵌套属性不会影响 obj1

3. 手写深拷贝(递归拷贝)

实现如下:

js 复制代码
function deepCopy(obj) {
    let newObj = {}
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            // 先判断 obj[key] 值的类型
            if (typeof obj[key] === 'object' && obj[key] !== null) { // 如果是对象
                newObj[key] = deepCopy(obj[key])
            } else {  // 如果不是对象
                newObj[key] = obj[key]
            }
        }
    }
    return newObj
}

用法举例

js 复制代码
const arr1 = [1, 2, { a: 3 }];
const arr2 = deepClone(arr1);
arr2[2].a = 100;
console.log(arr1); // [1, 2, { a: 3 }]

改变了 arr2 中 {a: 3} 的值,但是原数组 arr1 的值不变。

五、常见误区与注意点

  1. 浅拷贝只复制一层,嵌套对象还是"共用"。
  2. 深拷贝要递归,但要注意循环引用、特殊类型(如 Date、函数等)。
  3. JSON.parse(JSON.stringify(obj)) 不能拷贝 functionundefinedsymbol,也会丢失特殊对象。
  4. structuredClone 支持更全,但老浏览器不兼容。

六、总结

  • 浅拷贝 :只复制一层,嵌套对象共用引用。常用 Object.assign、展开运算符等。
  • 深拷贝 :递归复制所有层级,两个对象完全独立。常用 JSON 方法、structuredClone、手写递归。
相关推荐
菜鸟‍7 小时前
【前端学习】仿Deepseek官网AI聊天网站React
前端·学习·react.js
小光学长8 小时前
基于Vue的保护动物信息管理系统r7zl6b88 (程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
huangql5208 小时前
截图功能技术详解:从原理到实现的完整指南
前端·html5
长空任鸟飞_阿康8 小时前
Node.js 核心模块详解:fs 模块原理与应用
前端·人工智能·ai·node.js
这儿有一堆花9 小时前
网站链接重定向原理
前端
cecyci9 小时前
如何实现AI聊天机器人的打字机效果?
前端·javascript
IT_陈寒9 小时前
Vite 5个隐藏技巧让你的项目构建速度提升50%,第3个太香了!
前端·人工智能·后端
詩句☾⋆᭄南笙9 小时前
HTML的盒子模型
前端·html·盒子模型
落言9 小时前
AI 时代的工程师:懂,却非懂的时代
前端·程序员·架构
一枚攻城狮9 小时前
前端知识点大汇总
前端