深入理解JavaScript中的深拷贝与浅拷贝

在前端面试过程中,JS中的深浅拷贝是个非常经典的考点

面试官经常借此来考察候选人对数据类型、内存分配和对象引用的理解程度

本文将系统地介绍深浅拷贝的区别、原理和常见实现方式,并通过代码实例加以阐述

一、什么是浅拷贝(Shallow Copy)?

浅拷贝是指创建一个新的对象或数组,这个新对象对原对象的属性值进行精确的复制

然而,如果原对象的属性值是引用类型(如对象或数组),则浅拷贝只复制其引用,而不是具体的值

示例

let original = { name: "Alice", hobbies: ["reading", "coding"] };
let shallowCopy = Object.assign({}, original);

shallowCopy.name = "Bob";
shallowCopy.hobbies.push("swimming");

console.log(original); // { name: "Alice", hobbies: ["reading", "coding", "swimming"] }
console.log(shallowCopy); // { name: "Bob", hobbies: ["reading", "coding", "swimming"] }

可以看出,更改浅拷贝对象的引用类型属性时,原对象也随之发生了变化。

二、什么是深拷贝(Deep Copy)?

深拷贝会完全复制原对象中所有的值,包括嵌套的对象和数组,从而创建一个完全独立的新对象,新旧对象之间不存在共享引用

示例

常见的深拷贝方式之一是利用JSON进行序列化:

let original = { name: "Alice", hobbies: ["reading", "coding"] };
let deepCopy = JSON.parse(JSON.stringify(original));

// 修改深拷贝对象
deepCopy.name = "Bob";
deepCopy.hobbies.push("swimming");

console.log(original); // { name: "Alice", hobbies: ["reading", "coding"] }
console.log(deepCopy); // { name: "Bob", hobbies: ["reading", "coding", "swimming"] }

此时可以看到,修改深拷贝对象时,原对象不会受到任何影响。

三、浅拷贝与深拷贝的实现方式

浅拷贝常见方法

使用Object.assign()

使用扩展运算符…

使用数组方法如Array.slice()Array.concat()

let arr = [1, 2, 3];
let shallowArr = arr.slice();
shallowArr.push(4);

console.log(arr); // [1, 2, 3]
console.log(shallowArr); // [1, 2, 3, 4]

深拷贝常见方法

使用JSON.parse(JSON.stringify())(简单快速,但有局限性,如无法处理函数、Date、RegExp等)

使用递归函数实现深拷贝

function deepClone(obj) {
  if (typeof obj !== 'object' || obj === null) return obj;
  let copy = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepClone(obj[key]);
    }
  }
  return copy;
}

let original = { a: 1, b: { c: 2 } };
let clone = deepClone(original);
clone.b.c = 3;

console.log(original); // { a: 1, b: { c: 2 } }
console.log(clone); // { a: 1, b: { c: 3 } }

四、面试中常见问题与注意点

  • 如何判断何时使用深拷贝或浅拷贝?
    如果不想原数据被修改,尤其是处理嵌套复杂对象时,使用深拷贝

  • JSON序列化深拷贝的缺陷是什么?
    JSON方法无法处理函数、Symbol、RegExp、Date、循环引用等复杂结构

  • 如何解决循环引用问题?
    在深拷贝时维护一个WeakMap或Map,记录已复制的对象,避免重复引用

五、总结

理解深浅拷贝不仅能够帮助你避免开发过程中的坑,也能够让你在前端面试中脱颖而出

希望各位大家在学习路上不断精进,持续成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

名之以父

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值