淺談Javascript 淺拷貝和深拷貝的理解

   javascript中存儲對象都是存地址的。javascript

   淺拷貝:淺拷貝是都指向同一塊內存區塊,淺拷貝共用同一內存地址,你改值我也變。若是拷貝的對象裏面的值是一個對象或者數組,它就是淺拷貝,拷貝的知識引用地址。 js的Object.assign,jquery的extend方法都是淺拷貝,通常的等號賦值也是淺拷貝 。html

    

     上面vue裏面的兩個寫法也是淺拷貝,具體地址爲 https://cn.vuejs.org/v2/guide/list.html
vue

 

   深拷貝:深拷貝則是另外開闢了一塊區域,深拷貝是互不影響,你改值我也不變。angular裏面的 angular.copy 是深拷貝。java

   下面實例也能夠看出這一點:jquery

// 淺拷貝
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。在我這種狀況下,我以爲個人代碼量又能夠減小了,好比:ide

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 ui

相關文章
相關標籤/搜索