简单易懂的对象深、浅拷贝----javascript

前期理解

首先,得知道js中的数据类型有:基本数据类型与引用数据类型。
基本数据类型有:Boolean、Number、String、undefined
引用数据类型:Object(Function、Array、Symbol等) 

其次,基本数据类型被创建并赋值时,在内存中是存储在栈中的;而引用数据类型,在内存中是存放在堆中的,变量可以理解为有一个指针,指向堆的值。

最后,看一个demo

  const obj = {
        name: "王五",
        age: 18,
      };
      var a;
      var b = a;
      b = 1;
      console.log(obj.name); //王五
      const newObj = obj;
      newObj.name = "李四";
      console.log(obj.name); //李四
      console.log(newObj.name); //李四
      console.log(a); //undefined
      console.log(b);//1

从代码可以看出,基本数据类型a赋值给b后,b可以重新赋值,不影响a的值。而引用数据类型obj赋值newObj后,newObj的赋值操作会影响Obj原来的值,真是因为obj与newObj指向堆中同一个对象,会互相影响的,这是所谓的浅拷贝。

当我们需要进行复制一个对象,又不影响原对象时,就要使用到深拷贝了。

补充:利用扩展运算符、Object.assign() 实现的也是浅拷贝,因为当原对象包含子对象属性时,就不管用了,利用JSON.parse()和JSON.stringify()也是一样的效果

      const obj = {
        name: "王五",
        age: 18,
        info: function () {
          console.log(this.name + "在唱歌");
        },
        son: {
          name: "王五的儿子",
        },
      };
      // let newObj = deepCopy(obj);
      let newObj = Object.assign({}, obj);
      newObj.name = "李四";
      newObj.son.name = "李四的儿子";
      newObj.info(); // 李四在唱歌
      console.log(newObj.name); // 李四
      console.log(newObj.son.name); // 李四的儿子
      console.log(obj.name); // 王五
      console.log(obj.son.name); //李四的儿子
      obj.info(); // 王五在唱歌

实现深拷贝的方法

所谓的深拷贝,就是复制原对象,且新对象的任何操作都不影响原对象,等同于在内存中重新创建一个新对象。

 function deepCopy(obj) {
        let newObj;
        let objType = dataType(obj);
        if (objType === "Array" || objType === "Object") {
          if (objType === "Array") {
            newObj = [];
          } else {
            newObj = {};
          }
          for (const key in obj) {
            if (dataType(obj[key]) === "Object" || objType === "Array") {
              newObj[key] = deepCopy(obj[key]);
            } else {
              newObj[key] = obj[key];
            }
          }
        } else {
          newObj = obj;
        }
        return newObj;
      }
      //定义函数,来判断需要复制的数据的数据类型,这个函数可判断所有的js数据类型
      function dataType(params) {
        let typeStr = Object.prototype.toString.call(params);
        let endType = typeStr.slice(8, -1);
        return endType;
      }
      const obj = {
        name: "王五",
        age: 18,
        info: function () {
          console.log(this.name + "在唱歌");
        },
        son: {
          name: "王五的儿子",
        },
      };
      let newObj = deepCopy(obj);
      newObj.name = "李四";
      newObj.son.name = "李四的儿子";
      newObj.info(); // 李四在唱歌
      console.log(newObj.name); // 李四
      console.log(newObj.son.name); // 李四的儿子
      console.log(obj.name); // 王五
      console.log(obj.son.name); //王五的儿子
      obj.info(); // 王五在唱歌

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值