深拷贝 浅拷贝 深拷贝浅拷贝的方法

浅拷贝:浅拷贝拷贝的是对象的一层属性 如果对象里面还有对象则拷贝的是复杂数据类型的地址  浅拷贝一般使用Object.assign(给谁,拷贝谁){...对象名}

深拷贝:深拷贝拷贝的是对象的多层属性 如果对象里面还有对象 则继续拷贝 一般我们使用递归、lodash/cloneDeep或者是JSON.parse(JSON.stringify))=>后端给的数据涉及函数体 undefined则不能拷贝成功

来实现

 

<body>
    <script>
      const obj = {
        uname: "张三",
        age: 18,
        family: {
          baby: "小阿三",
        },
      };
      /* 
      浅拷贝:拷贝对象的一层属性 如果对象里面还有对象(复杂数据类型)则拷贝的是地址 两者之间会相互影响 浅拷贝只适用于简单数据类型
      深拷贝:拷贝对象的多层属性 如果对象里面还有对象 则继续拷贝 一般使用递归、lodash/cloneDeep或者Json,stringify()来实现
      */

      // 方法一:浅拷贝 Object.assign(给谁,拷贝谁)
      // let newObject = {};
      // Object.assign(newObject, obj);
      // newObject.uname = "ll"; //改名
      // console.log(newObject); //这里拷贝出来的方法是一个地址

      // console.log(obj); //原对象里面的属性值没有被修改
      // newObject.family.baby = "大阿三";
      // console.log(newObject);
      // console.log(obj); //原对象里面的方法也会被修改

      // 方法2:浅拷贝 {...对象名}
      const o = { ...obj };
      // 原数据中的方法的值(复杂数据类型)又被修改了
      o.family.baby = "复杂数据类型浅拷贝拷贝的是地址";
      console.log(obj);
    </script>
  </body>

 使用递归深拷贝

 

<body>
    <script>
      /* 
    深拷贝 :1.一般使用递归
            2.lodsh/cloneDeep
            3.JSON.parse(JSON.stringify())来实现
          */
      //  利用递归实现深拷贝
      let obj = {
        name: "zs",
        age: 17,
        msg: ["179", "1000000"],
        family: {
          cat: "菜包",
          dog: "肉包",
        },
      };

      // for (let k in obj) {
      //   // console.log(k); //所有的属性名name age msg family

      //   // console.log(obj[k]); //所有的属性值zs 17 179 1000000 菜包 肉包
      //   newObj[k] = obj[k];
      //   console.log(newObj);
      // }
      // 手写深拷贝 有缺陷
      let newObj = {};
      function deepClone(newObj1, oldObj) {
        for (let k in oldObj) {
          if (oldObj[k] instanceof Array) {
            // 开辟一个新数组
            newObj1[k] = [];
            deepClone(newObj1[k], oldObj[k]);
          } else if (oldObj[k] instanceof Object) {
            newObj1[k] = {};
            deepClone(newObj1[k], oldObj[k]);
          } else {
            newObj1[k] = oldObj[k];
          }
        }
        return newObj1;
      }
      const res = deepClone(newObj, obj);
      // console.log(res);
      res.family.cat = "闹闹"; //将原来复杂数据类型中的属性值修改为了闹闹
      console.log(res); //把菜包变成闹闹
      console.log(obj); //没有修改原数组
    </script>
  </body>

 

用lodash 进行深拷贝 _.cloneDeep(value)
<body>
    <!-- 先引用 -->
    <script src="./lodash.min.js"></script>
    <script>
      let obj = {
        name: "zs",
        age: 17,
        msg: ["179", "1000000"],
        family: {
          cat: "菜包",
          dog: "肉包",
        },
      };
      //用lodash 进行深拷贝 _.cloneDeep(value)
      const o = _.cloneDeep(obj);
      console.log(o);
      o.msg.push("3");
      o.family.dog = "哄哄";
      console.log(o); //深拷贝后修改成哄哄
      console.log(obj); //原数据没有被修改 还是肉包
      console.log(o === obj); //false
    </script>
  </body>

 

JSON.parse(JSON.stringify(obj))利用字符串的不可变性 将字符串转换成复杂数据类型 进行深拷贝
  <body>
    <script>
      const obj = {
        uname: "pink",
        age: 18,
        hobby: ["乒乓球", "足球"],
        family: {
          baby: "小pink",
        },
      };
      /*  
      // 深拷贝
    JSON.parse(JSON.stringify(obj))利用字符串的不可变性 将字符串转换成复杂数据类型 进行深拷贝
    JSON.stringify(obj) 将复杂数据类型转换为JSON字符串 
    */
      // 开辟一个新的空间
      const newObj = JSON.parse(JSON.stringify(obj)); //利用字符串的不可变性 把字符串转换成js数据类型
      newObj.family.baby = "小丸子";
      console.log(newObj); //小丸子 深拷贝后的新数据
      console.log(obj); //还是小pink 没有修改原数据

      //  拓展:字符串的不可变性 数据还是占内存的 不要大量拼接字符串 会导致内存泄漏
      // let str = "pink";
      // str = "123"; //数据还是占内存的
      // str = "red";
      // console.log(str);
    </script>
  </body>

 

 

posted @ 2022-11-27 13:07  噢噢噢J  阅读(54)  评论(0编辑  收藏  举报