浅谈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'}

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

  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 deepCopy(obj){
    if(!obj || typeof obj !== 'object'){
        return ;
    }
    var dcObj = Array.isArray(obj) ? [] : {};
    for(var key in obj){
        if(obj.hasOwnProperty(key)){
            if(obj[key] && typeof obj[key] === 'object'){
                dcObj[key] = Array.isArray(obj[key]) ? [] : {};
                dcObj[key] = deepCopy(obj[key]);
            }
            dcObj[key] = obj[key]
        }
    }
    return dcObj;
}


function deepClone(obj){
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                //判断ojb子元素是否为对象,如果是,递归复制
                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],
    b=deepClone(a);
a[0]=2;
console.log(a,b); // [2, 2, 3, 4]   //[1, 2, 3, 4]

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

猜你喜欢

转载自www.cnblogs.com/allenhua/p/10863208.html