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 


  • 相关阅读:
    git常用指令 github版本回退 reset
    三门问题 概率论
    如何高效的学习高等数学
    数据库6 关系代数(relational algebra) 函数依赖(functional dependency)
    数据库5 索引 动态哈希(Dynamic Hashing)
    数据库4 3层结构(Three Level Architecture) DBA DML DDL DCL DQL
    梦想开始的地方
    java String字符串转对象实体类
    java 生成图片验证码
    java 对象之间相同属性进行赋值
  • 原文地址:https://www.cnblogs.com/allenhua/p/10863208.html
Copyright © 2011-2022 走看看