再续深浅拷贝

前言:

之前深浅拷贝前前后后看了好几遍查看了好多资料,还是有那么一点迷糊,直到有一次看到了同学讲的ppt让我很受启发,接着我就理出了一条比较清晰的路来去理解js的深浅拷贝。要想理解深浅拷贝首先得分清,对象赋值,浅拷贝,深拷贝之间的关系。

在这之前咱们先把准备工作做好,先去理解的概念。

对于栈和堆的定义也比较复杂抽象,非常不好理解。在这里我就用大白话说一下我对堆和栈的理解——我们其实可以认为堆是存储数据的,而栈是存储地址的。我们可以试着想象一下这个场景,在进超市的时候要存放一些私人物品,就要到存储柜区存放物品。当我们存放的时候,会先到取票机里取一张小票,才能把物品存放到柜子里。这里栈是取票机,而小票就是地址。堆是柜子,而物品就是数据。

一、对象赋值

当我们把一个对象赋值给一个新变量的时候,赋的其实是该对象在栈中的地址,而不是堆中的数据。也就是两个对象指向同一个地址,无论哪个发生变化,都会改变地址里面的内容。因此,两个对象是联动的。 

      let obj = { id: 1, name: "jack", data: {content: "他们俩用一个黄色的脸盆"}};
      let newObj = obj;
      newObj.name = "rose";
      console.log(newObj);//{ id: 1, name: "rose", data: {content: "他们俩用一个黄色的脸盆"}}
      console.log(obj);//{ id: 1, name: "rose", data: {content: "他们俩用一个黄色的脸盆"}}

二、浅拷贝

重新在堆中创建内存,拷贝前后基本数据类型互不影响,但是拷贝前后对象的引用类型共享同一块内存,会互相影响。(拷贝前后,基本类型互不影响,对象互相影响)。

      let obj = {
        id: 0,
        name: "jack",
        data: { content: "他们俩用一个黄色的脸盆" },
      };
      //对象的浅拷贝可以用结构赋值
      // let newObj = { ...obj };
      //对象的浅拷贝可以用Object.assign
      let newObj = Object.assign({}, obj);
      newObj.id = 1;
      newObj.name = "rose";
      newObj.data.content = "他们俩用一个红色的脸盆洗脸";
      console.log(obj); //{ id: 0, name: "jack", data: {content: "他们俩用一个红色的脸盆"}};
      console.log(newObj); //{ id: 1, name: "rose", data: {content: "他们俩用一个红色的脸盆"}};

这里呢可以形象的理解为一个柜子前半格被开辟出一个新内存

 三、深拷贝

从堆内存中开辟一个新的区域存放新对象,拷贝前后两个对象互不影响。

      let obj = {
        id: 0,
        name: "jack",
        data: { content: "他们俩用一个黄色的脸盆" },
      };
      let newObj = JSON.parse(JSON.stringify(obj));
      newObj.id = 1;
      newObj.name = "rose";
      newObj.data.content = "rose用红色的脸盆";
      console.log(obj); //{ id: 0, name: "jack", data: {content: "他们俩用一个黄色的脸盆"}};
      console.log(newObj); //{ id: 1, name: "rose", data: {content: "rose用红色的脸盆"}};

这里也可以形象的理解为一个柜子被分开了两半,两个柜子互不影响。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
拷贝和浅拷贝都是常见的复制数据的方式。 浅拷贝只会复制对象的第一层属性,如果对象属性值是一个引用类型,那么复制的是该引用类型的地址,也就是说,新对象和原对象的该引用类型的属性指向同一个内存地址。当原对象的该引用类型的属性值发生变化时,新对象也会受到影响,因为它们指向的地址是相同的。 拷贝则会递归地复制对象及其所有嵌套的属性,直到所有属性都是基本类型或不可变类型时才停止。这样,新对象和原对象的所有属性都指向不同的内存地址,互不影响。 实现拷贝的方式有很多,以下列举几种: 1. 使用JSON.parse和JSON.stringify方法:先将对象转为字符串,然后再将字符串转回对象,这样可以实现拷贝,但是有一些限制,比如不能复制函数、正则表达式等特殊类型的数据。 ```javascript let newObj = JSON.parse(JSON.stringify(oldObj)); ``` 2. 使用递归函数:遍历对象的所有属性,如果属性值是对象,则递归调用该函数进行复制,这样可以实现完整的拷贝。 ```javascript function deepClone(obj) { if (typeof obj !== 'object' || obj === null) { return obj; } let result = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { result[key] = deepClone(obj[key]); } } return result; } ``` 以上列举了常见的拷贝和浅拷贝的方式,具体使用哪种方式取决于实际需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值