zoukankan      html  css  js  c++  java
  • 浅谈Javascript 浅拷贝和深拷贝的理解

       javascript中存储对象都是存地址的。

       浅拷贝:浅拷贝是都指向同一块内存区块,浅拷贝共用同一内存地址,你改值我也变。如果拷贝的对象里面的值是一个对象或者数组,它就是浅拷贝,拷贝的知识引用地址。 js的Object.assign,jquery的extend方法都是浅拷贝,一般的等号赋值也是浅拷贝 。

        

         上面vue里面的两个写法也是浅拷贝,具体地址为 https://cn.vuejs.org/v2/guide/list.html

       深拷贝:深拷贝则是另外开辟了一块区域,深拷贝是互不影响,你改值我也不变。angular里面的 angular.copy 是深拷贝。

       下面实例也可以看出这一点:

    // 浅拷贝
    const a = {t: 1, p: 'gg'};
    const b = a;
    b.t = 3;
    console.log(a); // {t: 3, p: 'gg'}
    console.log(b); // {t: 3, p: 'gg'}
    //深拷贝
    const c = {t: 1, p: 'gg'};
    const d = deepCopy(c);
    d.t = 3;
    console.log(c); // {t: 1, p: 'gg'}
    console.log(d); // {t: 3, p: 'gg'}
    //浅拷贝  es6 扩展运算符
    let a = [14,12,54,33,22];
    let b = a;  // 相当于copy
    a.push(44);
    console.log(a); // [14, 12, 54, 33, 22, 44]
    console.log(b); // [14, 12, 54, 33, 22, 44]
    
    //深拷贝
    let a = [14,12,54,33,22];
    let b = [...a];
    a.push(44);
    console.log(a); // [14, 12, 54, 33, 22, 44]
    console.log(b); // [14, 12, 54, 33, 22]

    可以明显看出,浅拷贝在改变其中一个值时,会导致其他也一起改变,而深拷贝不会。

      Object.assign() ————深拷贝神器,这个方法就是用来拷贝一个对象的,通常做法就是Object.assign({}, sourceObject, { key1: value1,key2: value2})  {}表示目标对象,会定义成一个空的{},sourceObjec就是源对象
    // Cloning an object
    var obj = { a: 1 };
    var copy = Object.assign({}, obj);
    console.log(copy); // { a: 1 }
    // Merging objects
    var o1 = { a: 1 };
    var o2 = { b: 2 };
    var o3 = { c: 3 };
    
    var obj = Object.assign(o1, o2, o3);
    console.log(obj); // { a: 1, b: 2, c: 3 }
    console.log(o1);  // { a: 1, b: 2, c: 3 }, target object itself is changed.
    console.log(o2);//{b: 2} 源对象没有变
    console.log(o3);// {c: 3}

    是不是很完美,又可以clone又可以merge。在我这种情况下,我觉得我的代码量又可以减少了,比如:

    const defaultOpt = {
        title: 'hello', 
        name: 'oo', 
        type: 'line'
    };
    // 原来可能需要这样
    const opt1 = deepCopy(a);
    opt1.title = 'opt1';
    opt1.type = 'bar';
    opt1.extra = 'extra'; // 额外增加配置
    // 现在只要这样
    const opt2 = Object.assign({}, a, {
        title: 'opt2', 
        type: 'bar', 
        extra: 'extra'
    });
    注:它只对顶层属性做了赋值,完全没有继续做递归之类的把所有下一层的属性做深拷贝。意思就是是拷贝一层,没有拷贝多层。
    一层
    {
       a: 1,
       b: 2,
    }
    
    多层
    {
       a: 1,
       b: 2,
       c: {
          d: 4,
          e: {
              f: 6,
              g: 7
          }
       }
    }

    实现深拷贝,遍历key

    function deepClone(obj){
        //判断obj是否为数组,如果是,初始化数组[],否则初始化对象{}
        let dcObj = Array.isArray(obj)?[]:{};
        if(obj && typeof obj==="object"){
            //循环
            for(key in obj){
                //判断对象是否有key属性
                if(obj.hasOwnProperty(key)){
                    //判断ojb子元素是否为对象,如果是,递归复制
                    if(obj[key]&&typeof obj[key] ==="object"){
                        dcObj[key] = deepClone(obj[key]);
                    }else{
                        //如果不是,简单复制
                        dcObj[key] = obj[key];
                    }
                }
            }
        }
        return dcObj;
    };
    let t1 = {
        "a": 1,
        "b": 2,
        "c": {
            "d": 4,
            "e": {
                "f": 6,
                "g": 7
            }
        }
    };
    let t2=deepClone(t1);
    t1.a=6;
    console.log(t1);
    /*
    {
        "a": 6,
        "b": 2,
        "c": {
            "d": 4,
            "e": {
                "f": 6,
                "g": 7
            }
        }
    }
    */
    console.log(t2); //t1深拷贝给t2, b属性的值还是为2,没有改变,所以是深拷贝
    /*
    {
        "a": 1,
        "b": 2,
        "c": {
            "d": 4,
            "e": {
                "f": 6,
                "g": 7
            }
        }
    }
    */

     参考:https://www.jianshu.com/p/a66050673663 


  • 相关阅读:
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(12月23日)
    北京Uber优步司机奖励政策(12月22日)
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(12月22日)
    北京Uber优步司机奖励政策(12月21日)
    PHP面向对象深入研究之【命名空间】与【自动加载类】
    PHP面向对象深入研究之【高级特性】
    PHP面向对象深入研究之【继承】,减少代码重复
    PHP实现物流查询(通过快递网API实现)
    PHP实现日志写入log.txt
    PHP 字符串 加*
  • 原文地址:https://www.cnblogs.com/allenhua/p/10863208.html
Copyright © 2011-2022 走看看