美文网首页
浅拷贝和深拷贝

浅拷贝和深拷贝

作者: fz_log | 来源:发表于2021-07-13 13:53 被阅读0次

    区别:
    1、数据类型是基础数据类型:名字和值都会储存在栈内存中,用浅拷贝不会存在什么问题
    2、引用数据类型的数据,名字存在栈内存中,值存在堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值(对于浅拷贝,这样是把饮用地址copy给对象存在隐患。无论是拷贝的对象内的数据比变化,还是被拷贝的对象变化,都会引起对方的变化


    image.png
    image.png

    实现浅拷贝的方法:
    (1) for···in 循环遍历拷贝第一层

    function simpleCopy(obj) { 
      var objCopy = Array.isArray(obj) ? [] : {};
      for (const key in obj) {
        objCopy[key] = obj[key];
      }
      return objCopy;
    }
    

    (2) object.assign()

    var obj = {
        a: 1,
        b: 2
    }
    var obj1 = Object.assign(obj);
    obj1.a = 3;
    console.log(obj.a) // 3
    

    (3) 直接赋值

    let a=[0,1,2,3,4],
       b=a;
    console.log(a===b);
    a[0]=1;
    console.log(a,b);
    

    实现深拷贝的方法
    (1)采用递归拷贝所有层级

    function deepClone(obj) {
      let objClone = Array.isArray(obj) ? [] : [];
      if (obj && typeof obj === "object") {
        for (const key in obj) {
          if (obj.hasOwnProperty(key)) {
            //判断obj子元素是否为对象,如果是,递归复制
            if (obj[key] && typeof obj[key] === "object") {
              objClone[key] = deepClone(obj[key]);
            }else {
              //如果不是简单复制
              objClone[key] = obj[key];
            }
          }
        }
      }
      return objClone;
    }
    let a=[1,2,[3,4],[5,6]],
        b=deepClone(a);
    a[0]=2;
    console.log(a,b);
    

    (2) 通过JSON对象实现深拷贝

    function deepClone(obj) {
      var _obj = JSON.stringify(obj),
      objClone = JSON.parse(_obj);
      return objClone;
    }
    缺点:无法对对象中的方法实行深拷贝,会显示undefined
    

    (3) 通过jQuery的extend进行深拷贝

    $.extend( [deep ], target, object1 [, objectN ] )
    

    (4) lodash 插件参拷贝

    // 导入lodash
    import _ from 'lodash'
    // loodash.cloneDeep(obj)深拷贝
    const form = _.cloneDeep(this.addForm)
    form.goods_cat = form.goods_cat.join(',')
    

    (5) 如果对象的value是基本数据类型 可以用Object.assign(),但是要把它赋值给一个空对象

    var obj = {
        a: 1,
        b: 2
    }
    var obj1 = Object.assign({}, obj); // obj赋值给一个空{}
    obj1.a = 3;
    console.log(obj.a);// 1
    

    (6)slice实现对数组的拷贝

    // 当数组里面的值是基本数据类型,比如String,Number,Boolean时,属于深拷贝
    // 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝
    var arr1 = ["1","2","3"]; 
    var arr2 = arr1.slice(0);
    arr2[1] = "9";
    console.log("数组的原始值:" + arr1 );
    console.log("数组的新值:" + arr2 );
    

    (7) concat 实现对数组的深拷贝

    // 当数组里面的值是基本数据类型,比如String,Number,Boolean时,属于深拷贝
    var arr1 = ["1","2","3"];
    var arr2 = arr1.concat();
    arr2[1] = "9";
    console.log("数组的原始值:" + arr1 );
    console.log("数组的新值:" + arr2 );
    // 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝
    var arr1 = [{a:1},{b:2},{c:3}];
    var arr2 = arr1.concat();
    arr2[0].a = "9";
    console.log("数组的原始值:" + arr1[0].a ); // 数组的原始值:9
    console.log("数组的新值:" + arr2[0].a ); // 数组的新值:9
    

    (8)直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。

    function deepClone(initalObj, finalObj) {    
      var obj = finalObj || {};    
      for (var i in initalObj) {        
        var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
        if(prop === obj) {            
          continue;
        }        
        if (typeof prop === 'object') {
          obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
        } else {
          obj[i] = prop;
        }
      }    
      return obj;
    }
    

    (9) 扩展符实现拷贝

    // 当value是基本数据类型,比如String,Number,Boolean时,是可以使用拓展运算符进行深拷贝的
    // 当value是引用类型的值,比如Object,Array,引用类型进行深拷贝也只是拷贝了引用地址,所以属于浅拷贝
    var car = {brand: "BMW", price: "380000", length: "5米"}
    var car1 = { ...car, price: "500000" }
    console.log(car1); // { brand: "BMW", price: "500000", length: "5米" }
    console.log(car); // { brand: "BMW", price: "380000", length: "5米" }
    

    (10) 手动赋值实现深拷贝(实际开发过程中不常用)

    let obj1 = {
     a: 1,
     b: 2
    }
    let obj2 = {
     a: obj1.a,
     b: obj1.b
    }
    obj2.a = 3;
    alert(obj1.a); // 1
    alert(obj2.a); // 3
    

    ---该文章内容来自 https://www.jianshu.com/p/1c142ec2ca45 主要用于方便个人查阅

    相关文章

      网友评论

          本文标题:浅拷贝和深拷贝

          本文链接:https://www.haomeiwen.com/subject/aperpltx.html