深拷貝VS淺拷貝

一、深拷貝和淺拷貝的概念

舉個(gè)栗子:

var a = {name:'Jack'};
var b = a;
b.name = 'Peter';
console.log(a.name) //'Peter'

從以上代碼可以看出,當(dāng)a是一個(gè)對(duì)象的時(shí)候,將a賦值給b,則b的屬性改變之后a的屬性也會(huì)相應(yīng)的改變(因?yàn)樗鼈冎赶蛄送粔K內(nèi)存),這就是淺拷貝。

與之相反的,若將a的屬性復(fù)制到b,而b重新指向另一塊內(nèi)存,則b里的屬性變化時(shí),a的屬性將不會(huì)被改變,這就是深拷貝。

并且,JavaScript中的七種數(shù)據(jù)類型中,基本類型(String、Number、Boolean、Symbol、null、undefined)在拷貝的時(shí)候,結(jié)果都符合深拷貝的定義,因此不在我們的討論范圍。

二、實(shí)現(xiàn)淺拷貝

1、直接賦值

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

2、用Object.assign()來(lái)實(shí)現(xiàn)

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

值得注意的是,當(dāng)obj1里的數(shù)據(jù)只有一層時(shí),Object.assign()是深拷貝

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

三、實(shí)現(xiàn)深拷貝

1、用遞歸實(shí)現(xiàn)

var Jack = {
        name : 'Jack',
        nationality :'US',
        friends:['Sally','Ryan']
};

function deepCopy(o,c){
    var c = c || {}
    for(var i in o){
        if(typeof o[i] === 'object'){
             if(o[i].constructor === Array){
                  c[i] =[]
             }else{
                  c[i] = {}
             }
             deepCopy(o[i],c[i])
       }else{
          c[i] = o[i]
       }
    }
       return c
};

var Peter = {};
deepCopy(Jack,Peter);
Peter.name = 'Peter';
console.log(Peter) //{name:'Peter',nationality:'US',friends:['Sally','Ryan']}
console.log(Jack)//{name:'Jack',nationality:'US',friends:['Sally','Ryan']}

2、用JSON.parse()JSON.stringfy()來(lái)實(shí)現(xiàn)

var target = {a: 1, b: 1, c: {c1: 11, c2: 12, c3: 13}};
var deepCopy = JSON.parse(JSON.stringify(target));
deepCopy.a = 2;
deepCopy.c.c1 = 21;
console.log(target);   // {a: 1, b: 1, c: {c1: 11, c2: 12, c3: 13}}
console.log(deepCopy);    // {a: 2, b: 1, c: {c1: 21, c2: 12, c3: 13}}
console.log(target === deepCopy);  // false

注:JSON.parse()JSON.stringfy()能夠正確處理的只有String、Number、Array等能夠被json表示的數(shù)據(jù)類型,不能被json表示的會(huì)丟失。

var target = {a:1,b:1,c:function(){console.log('hi')}};
var deepCopy = JSON.parse(JSON.stringfy(target));
console.log(deepCopy)//{a:1,b:1}

3、用jQuery.extend()來(lái)實(shí)現(xiàn)

var target = {a:1,b:1,c:{c1:11,c2:12,c3:13}};
var deepCopy = $.extend(true,{},target)
deepCopy.c.c2 = 22
console.log(deepCopy)//{a:1,b:1,c:{c1:11,c2:22,c3:13}}
console.log(target)//{a:1,b:1,c:{c1:11,c2:12,c3:13}}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容