javaScript中深淺拷貝學(xué)習(xí)筆記

深淺拷貝的概念:

由于引用類型在棧中只是存儲了數(shù)據(jù)存儲的地址,當(dāng)直接把一個對象賦值給另一個對象時,其實只是把地址復(fù)制而已,當(dāng)其中一個的值改變,另一個也對應(yīng)改變。這樣不是我們想要的結(jié)果,故而有了深淺拷貝;
淺復(fù)制:只復(fù)制一層(即當(dāng)對象中屬性值也為對象時不會進行深層次的復(fù)制,只復(fù)制一層)。
深復(fù)制:會遞歸復(fù)制(即當(dāng)對象中屬性值也為對象時會進行深層次復(fù)制,無論多少層)。

js的數(shù)據(jù)類型:

基本數(shù)據(jù)類型類型(即直接存儲在棧內(nèi)存中):Undefined、Null、Boolean、Number、String
引用類型(即存儲在堆內(nèi)存中):Object

淺拷貝:

數(shù)組的淺拷貝(在js中數(shù)組也是一種對象):

1、通過js自帶的方法來實現(xiàn)

    var x = [0,1,2,[3,4,[5,6]]];
    var shadow1 = x.slice(0);
    var shadow2 = x.concat();

    console.log(shadow1 === x);  //false  表示內(nèi)存中存儲位置不同(以下相同)
    console.log(shadow2 === x);  //false
    console.log(shadow1[3][2] === x[3][2]);  //true  表示內(nèi)存中存儲位置相同(以下相同)
    console.log(shadow2[3][2] === x[3][2]);  //true

從上面代碼可以看出它只實現(xiàn)了一層拷貝,故為淺拷貝
2、自己通過循環(huán)來實現(xiàn)淺拷貝

    function shadowCopy(arr) {
        if(typeof arr !== 'object'){
            console.log('your arg is not object');
            return;
        }else{
            var arr0 = [];
                for (var i = 0; i < obj.length; i++) {
                    arr0[i] = arr[i];
                }
        }
        return arr0;
    }
    var shadow = shadowCopy(x);  
    console.log(shadow === x);  //false
    console.log(shadow[3][2] === x[3][2]);  //true

對象的淺拷貝

    var x = {
        a: 1,
        b: 2,
        c: {
            d: 3,
            e: {
                f: 4
            }
        }
    }
    function shadowCopy(obj) {
        if(typeof obj !== 'object'){
            console.log('your arg is not object');
            return;
        }else{
             var obj0 = {};
             for (var i in obj) {
             obj0[i] = obj[i];
             }
        }
        return obj0;
    }
    var shadow = shadowCopy(x);  
    console.log(shadow === x);  //false
    console.log(shadow.c === x.c);  //true

深拷貝

1、通過JSON對象來實現(xiàn)(數(shù)組和標(biāo)準(zhǔn)對象都適用)

    var x = [0,1,2,[3,4,[5,6]]];
    var y = {
        a: 1,
        b: 2,
        c: {
            d: 3,
            e: {
                f: 4
            }
        }
    }
    var shadow1 = deepCopyJSON(x);
    var shadow2 = deepCopyJSON(y);

    console.log(shadow1 === x);  //false
    console.log(shadow1[3][2] === x[3][2]);  /false
    console.log(shadow2 === y);  //false
    console.log(shadow2.c.e === y.c.e);  //false

    function deepCopyJSON(obj) {
        if(typeof obj !== 'object'){
            console.log('your arg is not object');
        }else{
            return JSON.parse(JSON.stringify(obj));
        }
    }

2、通過第三方庫來實現(xiàn)(詳情參閱http://jerryzou.com/posts/dive-into-deep-clone-in-javascript/
3、自己實現(xiàn)(此方法數(shù)組和標(biāo)準(zhǔn)對象都適用)

    var x = [0,1,2,[3,4,[5,6]]];
    var y = {
        a: 1,
        b: 2,
        c: {
            d: 3,
            e: {
                f: 4
            }
        }
    }
    var shadow1 = deepCopyMyself(x);
    var shadow2 = deepCopyMyself(y);

    console.log(shadow1 === x);  //false
    console.log(shadow1[3][2] === x[3][2]);  //false
    console.log(shadow2 === y);  //false
    console.log(shadow2.c.e === y.c.e);  //false

    function deepCopyMyself(obj) {
        if(typeof obj !== 'object'){
            console.log('your arg is not object');
            return;
        }else{
            var obj0 = obj.constructor === Array ? [] : {};
            if(obj0.constructor === Object){
                for (var i in obj) {
                    obj0[i] = typeof obj[i] === 'object' ? deepCopyMyself(obj[i]) : obj[i];
                }
            }else{
                for (var i = 0; i < obj.length; i++) {
                    obj0[i] = typeof obj[i] === 'object' ? deepCopyMyself(obj[i]) : obj[i];
                }
            }
        }
        return obj0;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • underscore 的源碼中,有很多地方用到了 Array.prototype.slice() 方法,但是并沒有...
    theCoder閱讀 679評論 0 1
  • 值類型與引用類型 談淺拷貝與深拷貝之前,我們需要先理清一個概念,即值類型與引用類型。 什么是值類型與引用類型?這要...
    franose閱讀 662評論 1 8
  • 簡單講呢,深淺拷貝,都是進行復(fù)制,那么區(qū)別主要在于復(fù)制出來的新對象和原來的對象是否會互相影響,改一個,另一個也會變...
    _千尋瀑_閱讀 312評論 0 2
  • 前言 本文要解決的問題: 為什么會有深拷貝(deep clone)和淺拷貝(shallow clone)的存在 理...
    無亦情閱讀 1,938評論 0 5
  • 頁面編寫心得 先分清項目中的公有邏輯和私有邏輯,把公有邏輯抽離出來。面向?qū)ο缶幊?,而不是面向過程編程。 例子1,一...
    涂行知閱讀 4,830評論 0 0

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