深拷贝与浅拷贝

判断深拷贝还是浅拷贝:修改拷贝之后的数据会不会影响原数据,浅拷贝会影响

// 浅拷贝1:直接赋值
     let obj = {
        username: "kobe",
        age: 39,
        sex: { option1: "男", option2: "女" },
      };
      let obj1 = obj;
      console.log(obj1);//...option1: "男"...
      obj1.sex.option1 = "233"; // 修改复制的对象会影响原对象
      console.log(obj1, obj);//...option1: "233"...
      
    // 浅拷贝2:Object.assign()
    // Object.assign(target, source1, source2..) : 将源对象的属性复制      到目标对象上
      let obj = {
        username: "kobe",
        age: 39,
        sex: { option1: "男", option2: "女" },
      };
      let obj2 = {};
      Object.assign(obj2, obj);
      obj2.age = 18; //深拷贝(不同时改变)
      obj2.sex.option1 = "男123"; //浅拷贝(同时改变)
      console.log(obj2, obj);
      //obj和obj2对应的age不同,option1相同(数组同)
      
// 浅拷贝3:扩展运算符...
     const obj1 = {
        name: "peiqi",
        info: {
          age: 18,
        },
      };
      const obj2 = { ...obj1 };
      obj2.name = "kebi"; //深拷贝(不同时改变)
      obj2.info.age = 22; //浅拷贝(同时改变)
      console.log(obj1, obj2);
      // 浅拷贝4: arr.concat(): 数组浅拷贝
    let arr = [1, 2, 3, { username: "kobe" }];
      let testArr = [4, 5];
      let arr2 = [];
      arr2 = arr.concat();
      arr2[2] = 88888;//深拷贝(不同时改变)
      arr2[3].username = "wade";//浅拷贝(同时改变)
    // 浅拷贝5:arr.slice(): 数组浅拷贝
    let arr = [1, 2, 3, { username: "kobe" }];
    let arr3 = arr.slice(0);
    arr3[2] = 6;//深拷贝(不同时改变)
    arr3[3].username = 'duncan';//浅拷贝(同时改变)
      
      
//深拷贝
    //JSON.parse(JSON.stringify(arr/obj)) 只能深拷贝js对象/数组
     let obj = {username: 'kobe',  age: 43};
     let obj2 = JSON.parse(JSON.stringify(obj))
     console.log(obj2);
     obj2.username = 'wade';
     console.log(obj2, obj);//wade kobe
     //无法深拷贝的点:
     //1.拷贝的对象的值中如果有函数/undefined/symbol类型,不会转换,而是丢弃(图1)
 function person(name) {
        let a= 1;
      }
      const newObj = JSON.parse(JSON.stringify(person));
      
//2.无法处理循环引用(即对象的某个属性引用了该对象本身)(图2)
let obj = { username: "kobe", age: 43 }; 
      obj.a = obj;
      let obj2 = JSON.parse(JSON.stringify(obj));
      console.log(obj2, obj); //obj2的uasername:wade,obj2的uasername:Kobe
     //3.拷贝Date引用类型会变成字符串,拷贝RegExp,Error引用类型会变成空对象(图1)
let obj = {
        a: /abc/,
        b: new Error("error"),
        c: new Date(),
      };
      let obj2 = JSON.parse(JSON.stringify(obj));
      console.log(obj2, obj); 
      //2.无法拷贝对象的原型链(图4)
function Person(name) {
        this.name = name;
      }
      Person.prototype.say = function () {
        alert("Hi!!!");
      };
      const obj = new Person("Tom");
      const newObj = JSON.parse(JSON.stringify(obj));
      console.log(newObj, obj);
      newObj.say();

图1
在这里插入图片描述
图2
在这里插入图片描述
图3
在这里插入图片描述
图4
在这里插入图片描述

自定义实现深拷贝

实现深拷贝
      function checkoutType(target){
          return Object.prototype.toString.call(target).slice(8,-1);
      }
      function clone(target){
          let result;
          let targetType= checkoutType(target)
          if( targetType === 'Array'){
              result = [];
          }else if(targetType === 'Object'){
              result = {};
          }else{
              return target;
          }

          for(let item in target){
              let value = target[item];
              if (checkoutType(value) === 'Array'||'Object'){
                  result[item] = clone(value);
              }else{
                  result[item] = value;
              }

          }
          return result;
      }
      let obj  = {name:'kobe',age:43,hobby:['basketball','football']};
      let obj2 =clone(obj);
      console.log(obj,obj2);//{name: "kobe", age: 43, hobby: Array(2)} {name: "kobe", age: 43, hobby: Array(2)}
      obj2.name = 'wade';
      console.log(obj,obj2);//{name: "kobe", age: 43, hobby: Array(2)} {name: "wade", age: 43, hobby: Array(2)}
      obj2.hobby[0] = 'paino';
      console.log(obj,obj2);//{name: "kobe", age: 43, hobby: Array(2)}hobby: (2) ["basketball", "football"]
                            // {name: "wade", age: 43, hobby: Array(2)}hobby: (2) ["paino", "football"]

总结

1.浅拷贝:直接赋值
Object.assign()扩展运算符arr.concat()arr.slice()真正意义上既不是深拷贝,也不是浅拷贝。他只能深拷贝第一层,第二层为浅拷贝
2.深拷贝:
JSON.parse(JSON.stringify(arr/obj)) 只能深拷贝js对象/数组不能拷贝函数、undefined、循环引用、RegExp、Error、Date、对象的原型链上的属性等
参考使用Object.prototype.toString.call实现自定义深拷贝。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值