浅拷贝和深拷贝

以下是浅拷贝(Shallow Copy)和深拷贝(Deep Copy)的详细解释和对比:

一、核心区别

特性浅拷贝深拷贝
复制层级只复制对象的第一层属性(基本类型直接复制值,引用类型复制内存地址)递归复制对象的所有层级属性(包括嵌套对象、数组等),创建完全独立的副本
内存引用嵌套的引用类型数据与原对象共享内存(修改会相互影响)所有层级数据与原对象完全独立(修改互不影响)
适用场景简单数据结构(无嵌套引用类型)复杂数据结构(包含嵌套对象、数组等)

二、示例说明

1. 浅拷贝示例
const original = {
  name: "Alice",
  hobbies: ["reading", "music"]
};

// 浅拷贝方法:展开运算符
const shallowCopy = { ...original };

// 修改浅拷贝的顶层属性
shallowCopy.name = "Bob";
console.log(original.name); // "Alice"(原对象未受影响)

// 修改浅拷贝的嵌套引用属性
shallowCopy.hobbies.push("coding");
console.log(original.hobbies); // ["reading", "music", "coding"] ❌ 原对象被影响!

 2. 深拷贝示例

const original = {
  name: "Alice",
  hobbies: ["reading", "music"]
};

// 深拷贝方法:JSON 序列化(有局限性,见下文)
const deepCopy = JSON.parse(JSON.stringify(original));

// 修改深拷贝的嵌套属性
deepCopy.hobbies.push("coding");
console.log(original.hobbies); // ["reading", "music"] ✅ 原对象不受影响!

三、实现方式

1. 浅拷贝方法

方法示例适用场景
展开运算符 ...const copy = { ...obj };对象/数组的浅拷贝
Object.assign()const copy = Object.assign({}, obj);对象的浅拷贝
Array.slice()const copy = arr.slice();数组的浅拷贝
Array.concat()const copy = [].concat(arr);数组的浅拷贝

2. 深拷贝方法

 

方法示例优缺点
JSON.parse(JSON.stringify())const copy = JSON.parse(JSON.stringify(obj));✅ 简单<br/>❌ 无法处理函数、undefined、循环引用、Date 对象等
第三方库(如 lodash)_.cloneDeep(obj);✅ 处理复杂对象<br/>❌ 需引入外部库
手动递归实现自定义递归函数遍历所有属性✅ 完全控制<br/>❌ 代码复杂,需处理边界条件

四、深拷贝的手动实现

function deepClone(obj) {
  if (typeof obj !== "object" || obj === null) {
    return obj; // 基本类型直接返回
  }

  const copy = Array.isArray(obj) ? [] : {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepClone(obj[key]); // 递归拷贝
    }
  }
  return copy;
}

// 使用示例
const original = { a: 1, b: { c: 2 } };
const deepCopy = deepClone(original);

 

五、注意事项

  1. 性能问题

    • 深拷贝比浅拷贝更耗资源(尤其是大型对象)。
    • 避免在频繁操作中使用深拷贝。
  2. 特殊数据类型

    • DateRegExpFunction 等需要特殊处理(JSON 方法会丢失信息)。
  3. 循环引用

    • 当对象属性间接引用自身时,JSON 方法和简单递归会报错,需额外处理。

六、总结

操作是否共享内存修改嵌套数据的影响复杂度
直接赋值✅ 是相互影响
浅拷贝✅ 是(仅嵌套层)嵌套数据相互影响
深拷贝❌ 否完全独立

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值