【JavaScript】你知道深拷贝浅拷贝吗?深拷贝浅拷贝有什么区别?


深拷贝浅拷贝是什么?

在 JavaScript 开发中,深拷贝和浅拷贝是处理对象和数组的常见操作。它们涉及到复制数据结构以及处理引用类型数据的方式。
深拷贝和浅拷贝在不同的场景中有各自的应用。浅拷贝适用于简单的数据结构,当我们只需要复制基本数据类型的值或者共享引用类型数据时。而深拷贝则适用于需要完全独立的副本,以避免原始数据的修改对拷贝对象造成影响的情况。

1.浅拷贝

定义:浅拷贝是指创建一个新对象,这个新对象对原始对象的属性进行逐一复制。如果属性是基本类型(如字符串、数字、布尔值等),则复制的是值。如果属性是引用类型(如对象、数组),则复制的是引用。这意味着拷贝的新对象和原始对象共享同一个引用类型的属性。

1.1常见的浅拷贝方法:

Object.assign

const original = { a: 1, b: { c: 2 } };
const copy = Object.assign({}, original);
copy.b.c = 3;

console.log(original.b.c); // 输出: 3
console.log(copy.b.c);     // 输出: 3

扩展运算符(Spread Operator)

const original = { a: 1, b: { c: 2 } };
const copy = { ...original };
copy.b.c = 3;

console.log(original.b.c); // 输出: 3
console.log(copy.b.c);     // 输出: 3

Array.prototype.slice(用于数组):

const original = [1, 2, { a: 3 }];
const copy = original.slice();
copy[2].a = 4;

console.log(original[2].a); // 输出: 4
console.log(copy[2].a);     // 输出: 4

2.深拷贝

定义:深拷贝是指创建一个新对象,新对象完全复制原始对象的所有属性,包括嵌套的对象和数组。深拷贝后的新对象与原始对象完全独立,修改新对象的属性不会影响原始对象,反之亦然。

2.1深拷贝的方法:

JSON.parseJSON.stringify

const original = { a: 1, b: { c: 2 } };
const copy = JSON.parse(JSON.stringify(original));
copy.b.c = 3;

console.log(original.b.c); // 输出: 2
console.log(copy.b.c);     // 输出: 3
  • 优点:简单易用。
  • 缺点:不能拷贝函数、undefinedSymbol,且无法处理循环引用。

递归方法

function deepClone(obj) {
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }

    if (Array.isArray(obj)) {
        const copy = [];
        for (let i = 0; i < obj.length; i++) {
            copy[i] = deepClone(obj[i]);
        }
        return copy;
    }

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

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

console.log(original.b.c); // 输出: 2
console.log(copy.b.c);     // 输出: 3

使用第三方库(如 lodashcloneDeep 方法):

const _ = require('lodash');

const original = { a: 1, b: { c: 2 } };
const copy = _.cloneDeep(original);
copy.b.c = 3;

console.log(original.b.c); // 输出: 2
console.log(copy.b.c);     // 输出: 3

3.浅拷贝和深拷贝的区别

  • 复制的深度

    • 浅拷贝:只复制对象或数组的顶层属性,嵌套对象或数组只是引用。
    • 深拷贝:递归地复制所有层级的属性,嵌套对象或数组也会被完全复制。
  • 独立性

    • 浅拷贝:新对象和原始对象共享嵌套对象或数组的引用,修改一个会影响另一个。
    • 深拷贝:新对象与原始对象完全独立,修改一个不会影响另一个。

4.作用场景

  • . 浅拷贝适用场景

    • 属性层级较浅的对象或数组。
    • 不担心嵌套对象或数组共享引用的情况。
    • 性能要求较高的场景,浅拷贝的性能开销较小。
  • . 深拷贝适用场景

    • 属性层级较深的对象或数组。
    • 需要完全独立的副本,防止原始对象和新对象之间的相互影响。
    • 需要处理复杂对象结构,包括嵌套对象、数组和循环引用的情况。

总结

浅拷贝和深拷贝在 JavaScript 中是两种常见的对象或数组复制方式。浅拷贝只复制对象或数组的顶层属性,而深拷贝会递归地复制所有嵌套的属性。选择使用哪种拷贝方式取决于具体的应用场景和性能要求。理解它们的区别和适用场景,有助于编写更健壮和高效的代码。

  • 24
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值