JS的浅拷贝和深拷贝

本文介绍了浅拷贝的概念,其只复制对象一层属性的引用,导致多层嵌套时修改会互相影响。对比之下,深拷贝复制的是完整对象,不受嵌套影响。讲解了常用方法如Object.assign、扩展运算符和lodash的_.cloneDeep以及JSON.stringify/parse实现深拷贝。
摘要由CSDN通过智能技术生成

首先理解什么是浅拷贝和深拷贝:

浅拷贝:

  • 浅拷贝只会复制对象的第一层属性,而不会递归地复制嵌套的对象。
  • 浅拷贝仅复制对象的引用,新对象和原始对象仍然共享相同的引用,因此对新对象的修改可能会影响到原始对象。
  • 浅拷贝方法包括Object.assign()、扩展运算符...等。

代码解释:

const obj = {
            uname:'pink',
            age:18,
            family:{
                baby:'一'
            }
        }
        const o = {...obj};
        o.age = 20;
        console.log(obj.age);//18
        console.log(o.age);//20

这是浅拷贝  只会复制对象的第一次层属性   因此会看到两个对象的age值不一样

再看对象嵌套多层对象时的输出:

const obj = {
            uname:'pink',
            age:18,
            family:{
                baby:'一'
            }
        }
        
        const o = {};
        Object.assign(o,obj);
        o.age = 20;
        o.family.baby = '二';
        console.log(obj.age);//18
        console.log(o.age);//20
        console.log(obj.family.baby);//二
        console.log(o.family.baby);//二

这里我们可以看到  浅拷贝在我们只有一层属性的时候 修改不会对源对象造成影响,但是当源对象中有多层对象的时候  对于o.family.baby的赋值操作,由于oobj对象都引用了相同的family对象,所以修改o.family.baby实际上也会影响到obj.family.baby。这是因为浅拷贝只复制对象的引用,所以当引用指向的对象发生改变时,所有引用该对象的变量都会受到影响。当执行Object.assign(o, obj)时,o对象获得了obj对象的属性和值。所以,o.age的赋值操作并不会影响到obj.age,因为这只是修改了o对象的属性值,并没有改变原始的obj对象。

常用方法:

  1. 拷贝对象:Object.assgin()/展开运算符{...obj}拷贝对象

  2. 拷贝数组:Array.prototype.concat()或者[...arr]

直接赋值获得前拷贝有什么区别?

  • 直接赋值的方法,只要是对象,都会影响,因为是直接拷贝对象栈的地址

  • 浅拷贝如果是一层对象,不相互影响,如果出现多层对象拷贝还是回相互影响

浅拷贝怎么理解?

  • 拷贝对象之后,里面的属性值是简单数据类型直接拷贝值

  • 如果属性值是引用数据类型则拷贝的是地址

深拷贝:

深拷贝:拷贝的是对象,不是地址

常用的方法:

  1. 通过递归实现深拷贝

  2. lodash/cloneDeep

    语法:_.cloneDeep(要被克隆的对象);
    const o = _.cloneDeep(obj);

  3. 通过JSON.stringify()实现

    常用使用JSON方法:
    1. const obj = {
                  uanme:'pink',
                  age:18,
                  hobby:['乒乓球','足球'],
                  family:{
                      baby:'小pink'
                  }
              }
      
              //把对象转换成JSON字符串
              // console.log(JSON.stringify(obj));
              /*
              {"uanme":"pink","age":18,"hobby":["乒乓球","足球"],"family":{"baby":"小pink"}}
              */
              const o = JSON.parse(JSON.stringify(obj));
              console.log(o);
              o.family.baby = '123';
              console.log(o);
              console.log(obj);
      这里的const o = JSON.parse(JSON.stringify(obj));console.log(o);输出的值为:
      1. 这里的baby的值改变下因为下面的 o.family.baby = '123'; 对它进行了改变
      2. 当我们输出那个值的时候会发现和上面的一模一样:
      3. 而当我们输出obj的值的时候会发现它的baby的值并没有改变:

这就是深拷贝 当拷贝的对象发生变化时  源对象不会发生变化

JavaScript中,浅拷贝是指只拷贝了对象的一层内容,而引用类型的深层次数据仍然共享内存地址。简单来说,浅拷贝只是拷贝了对象的外层,而没有完全拷贝整个对象的内容。 举个例子,如果有一个数组里面包含了另一个数组或对象,浅拷贝只会拷贝外层的数组,而深层次的数组或对象仍然是共享内存地址的。 在JavaScript中,有一些常见的浅拷贝方法,比如使用Object.assign()方法可以将一个对象的属性拷贝到另一个对象中。通过Object.assign()方法,我们可以将源对象的属性浅拷贝到目标对象中。对于目标对象的已有属性,如果与源对象中的属性重复,那么源对象的属性会覆盖目标对象的属性值。 综上所述,浅拷贝只是拷贝了对象的一层内容,并不能改变对象的地址,所以深层次的引用类型仍然是共享内存地址的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [JS深拷贝浅拷贝](https://blog.csdn.net/baidu_33438652/article/details/124219924)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [js浅拷贝深拷贝](https://blog.csdn.net/weixin_57660141/article/details/126060089)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值