javaScript中的浅拷贝和深拷贝详解

在 JavaScript 中,浅拷贝深拷贝 的主要区别在于它们如何处理对象中的嵌套对象(即对象的属性也是对象的情况)。

1. 浅拷贝

浅拷贝只复制对象的第一层属性。如果对象的属性是一个引用类型(如对象或数组),浅拷贝只会复制该引用的地址,而不是实际的值。这意味着,如果你修改了拷贝对象中引用类型的属性,原对象中的该属性也会被修改。

常见的浅拷贝方式:
  • Object.assign()
  • 扩展运算符 ...
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = Object.assign({}, obj1);
// 或者
let obj3 = { ...obj1 };

// 修改 obj2 中的 b 属性
obj2.b.c = 3;

console.log(obj1.b.c); // 输出 3,因为 obj1 和 obj2 共享同一个 b 对象的引用

2. 深拷贝

深拷贝会递归地复制对象的所有层次,包括嵌套的对象和数组。这意味着拷贝后的对象和原对象完全独立,修改拷贝对象的任意部分都不会影响原对象。

实现深拷贝的常见方法:
1. 使用 JSON.stringify()JSON.parse()

这是一种简单但不太灵活的方法,它会将对象序列化为 JSON 字符串,再解析为新对象。它有一些局限性,比如不能处理 undefined、函数、循环引用等复杂数据结构。

let obj1 = { a: 1, b: { c: 2 } };
let obj2 = JSON.parse(JSON.stringify(obj1));

// 修改 obj2 中的 b 属性
obj2.b.c = 3;

console.log(obj1.b.c); // 输出 2,因为 obj1 和 obj2 是完全独立的
2. 递归实现深拷贝:

为了实现更健壮的深拷贝,可以手动递归地复制对象的每一层属性。

function deepClone(obj) {
    // 如果不是对象或者是 null,直接返回原值
    if (typeof obj !== "object" || obj === null) {
        return obj;
    }

    // 创建一个新的对象或数组,取决于原始对象的类型
    let newObj = Array.isArray(obj) ? [] : {};

    for (let key in obj) {
        // 确保该属性是对象自己的(而不是继承的)
        if (obj.hasOwnProperty(key)) {
            // 递归地拷贝属性值
            newObj[key] = deepClone(obj[key]);
        }
    }

    return newObj;
}

let obj1 = { a: 1, b: { c: 2 } };
let obj2 = deepClone(obj1);

obj2.b.c = 3;

console.log(obj1.b.c); // 输出 2,拷贝是深层的
3. 使用 Lodash 库的 cloneDeep 方法:

Lodash 是一个流行的 JavaScript 工具库,它提供了一个强大的深拷贝方法 _.cloneDeep(),可以处理复杂的数据结构。

let _ = require('lodash'); // 引入 lodash 库
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = _.cloneDeep(obj1);

obj2.b.c = 3;

console.log(obj1.b.c); // 输出 2

深拷贝和浅拷贝的应用场景:

  • 浅拷贝 适合简单的、没有嵌套对象的数据结构。
  • 深拷贝 在处理包含复杂对象、嵌套对象或数组时更为合适,因为这确保了数据的独立性。

总结:

  • 浅拷贝:只复制第一层的属性,嵌套对象引用仍然指向原来的对象。
  • 深拷贝:递归复制所有层次的属性,拷贝后的对象与原对象完全独立。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

前端李易安

打赏1元鼓励作者

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

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

打赏作者

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

抵扣说明:

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

余额充值