国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

js深淺復(fù)制

Apollo / 487人閱讀

摘要:總結(jié)綜上所述,數(shù)組的深拷貝比較簡(jiǎn)單,方法沒有什么爭(zhēng)議,對(duì)象的深拷貝,比較好的方法是用的方法實(shí)現(xiàn),或者遞歸實(shí)現(xiàn),比較簡(jiǎn)單的深復(fù)制可以使用實(shí)現(xiàn)參考資料知乎中的深拷貝和淺拷貝深入剖析的深復(fù)制

深淺復(fù)制對(duì)比

因?yàn)镴avaScript存儲(chǔ)對(duì)象都是存地址的,所以淺復(fù)制會(huì)導(dǎo)致 obj 和obj1 指向同一塊內(nèi)存地址。我的理解是,這有點(diǎn)類似數(shù)據(jù)雙向綁定,改變了其中一方的內(nèi)容,都是在原來的內(nèi)存基礎(chǔ)上做修改會(huì)導(dǎo)致拷貝對(duì)象和源對(duì)象都發(fā)生改變,而深復(fù)制一般都是開辟一塊新的內(nèi)存地址,將原對(duì)象的各個(gè)屬性逐個(gè)復(fù)制出去。對(duì)拷貝對(duì)象和源對(duì)象各自的操作不影響另一方

代碼層面實(shí)現(xiàn)深淺復(fù)制
//數(shù)組拷貝

//淺復(fù)制,雙向改變,指向同一片內(nèi)存空間
let arr = [1, 2, 3];
let arr1 = arr;
arr1[1] = "test";
console.log("shallow copy: " + arr + " " + arr1);   //shallow copy: 1,test,3 1,test,3

//深復(fù)制,開辟新的內(nèi)存區(qū)

//方法一:slice,原理:slice返回一個(gè)新數(shù)組
let deepArr = [1, 2, 3];
let deepArr1 = deepArr.slice(0);
deepArr1[1] = "test";
console.log("deep copy: " + deepArr + " " + deepArr1);   //deep copy: 1,2,3 1,test,3

//方法二:concat,原理:concat返回一個(gè)新數(shù)組
let deepArr2 = [1, 2, 3];
let deepArr3 = deepArr2.concat();
deepArr3[1] = "test";
console.log("deep copy: " + deepArr2 + " " + deepArr3);   //deep copy: 1,2,3 1,test,3

//知乎看到的深復(fù)制方法,這個(gè)函數(shù)可以深拷貝 對(duì)象和數(shù)組,很遺憾,對(duì)象里的函數(shù)會(huì)丟失
deepCloneObj = obj => {
    let str, newobj = obj.constructor === Array ? [] : {};
    if(typeof obj !== "object") {
        return;
    }else if(window.JSON) {
        /*好處是非常簡(jiǎn)單易用,但是壞處也顯而易見,會(huì)丟失很多東西,這會(huì)拋棄對(duì)象的constructor,
        也就是深復(fù)制之后,無論這個(gè)對(duì)象原本的構(gòu)造函數(shù)是什么,在深復(fù)制之后都會(huì)變成Object。
        另外諸如RegExp對(duì)象是無法通過這種方式深復(fù)制的。
        */
        str = JSON.stringify(obj);
        newobj = JSON.parse(str);
        //console.log(JSON.parse(JSON.stringify(/[0-9]/)));
    }else {
        for(let i in obj) {
            newobj[i] = typeof obj[i] === "object" ? deepCloneObj(obj[i]) : obj[i];
        }
    }
    return newobj;
}

let deepArr4 = {
    a: 1,
    b: "test",
    c: [1, 2, 3],
    d: {
        "a": "d:a",
        "b": "d:b"
    }
}
deepArr5 = deepCloneObj(deepArr4);
deepArr5["a"] = "testa";
console.log("deep copy: " + JSON.stringify(deepArr4) + " " + JSON.stringify(deepArr5));
/*deep copy: {"a":1,"b":"test","c":[1,2,3],"d":{"a":"d:a","b":"d:b"}} 
{"a":"testa","b":"test","c":[1,2,3],"d":{"a":"d:a","b":"d:b"}}
*/
第三方庫實(shí)現(xiàn)深淺復(fù)制

1.jQuery.extend
第一個(gè)參數(shù)可以是布爾值,用來設(shè)置是否深度拷貝的:

jQuery.extend(true, { a : { a : "a" } }, { a : { b : "b" } } );
jQuery.extend( { a : { a : "a" } }, { a : { b : "b" } } );

下面是源碼,可以看看

jQuery.extend = jQuery.fn.extend = function() {
    var src, copyIsArray, copy, name, options, clone,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false;

    // Handle a deep copy situation
    if ( typeof target === "boolean" ) {
        deep = target;

        // skip the boolean and the target
        target = arguments[ i ] || {};
        i++;
    }

    // Handle case when target is a string or something (possible in deep copy)
    if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
        target = {};
    }

    // extend jQuery itself if only one argument is passed
    if ( i === length ) {
        target = this;
        i--;
    }

    for ( ; i < length; i++ ) {
        // Only deal with non-null/undefined values
        if ( (options = arguments[ i ]) != null ) {
            // Extend the base object
            for ( name in options ) {
                src = target[ name ];
                copy = options[ name ];

                // Prevent never-ending loop
                if ( target === copy ) {
                    continue;
                }

                // Recurse if we"re merging plain objects or arrays
                if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                    if ( copyIsArray ) {
                        copyIsArray = false;
                        clone = src && jQuery.isArray(src) ? src : [];

                    } else {
                        clone = src && jQuery.isPlainObject(src) ? src : {};
                    }

                    // Never move original objects, clone them
                    target[ name ] = jQuery.extend( deep, clone, copy );

                // Don"t bring in undefined values
                } else if ( copy !== undefined ) {
                    target[ name ] = copy;
                }
            }
        }
    }

    // Return the modified object
    return target;
};

2.lodash —— _.clone() / _.cloneDeep()
在lodash中關(guān)于復(fù)制的方法有兩個(gè),分別是_.clone()和_.cloneDeep()。其中_.clone(obj, true)等價(jià)于_.cloneDeep(obj)。使用上,lodash和jquery并沒有太大的區(qū)別,但看了源碼會(huì)發(fā)現(xiàn), jQuery 不過60多行。可 lodash 中與深復(fù)制相關(guān)的代碼卻有上百行.jQuery 無法正確深復(fù)制 JSON 對(duì)象以外的對(duì)象,lodash 花了大量的代碼來實(shí)現(xiàn) ES6 引入的大量新的標(biāo)準(zhǔn)對(duì)象。更厲害的是,lodash 針對(duì)存在環(huán)的對(duì)象的處理也是非常出色的。因此相較而言,lodash 在深復(fù)制上的行為反饋比jquery好很多,是更擁抱未來的一個(gè)第三方庫。

總結(jié)

綜上所述,數(shù)組的深拷貝比較簡(jiǎn)單,方法沒有什么爭(zhēng)議,對(duì)象的深拷貝,比較好的方法是用lodash的方法實(shí)現(xiàn),或者遞歸實(shí)現(xiàn),比較簡(jiǎn)單的深復(fù)制可以使用JSON.parse(JSON.stringify(obj))實(shí)現(xiàn)

參考資料

知乎:javascript中的深拷貝和淺拷貝

深入剖析 JavaScript 的深復(fù)制

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/79930.html

相關(guān)文章

  • JS專題之深淺拷貝

    摘要:在之前的文章專題之?dāng)?shù)據(jù)類型和類型檢測(cè)中我有講過,中的數(shù)據(jù)類型分為兩種,基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,基本數(shù)據(jù)類型是保存在棧的數(shù)據(jù)結(jié)構(gòu)中的是按值訪問,所以不存在深淺拷貝問題。 前言 在開發(fā)過程中,偶爾會(huì)遇到這種場(chǎng)景,拿到一個(gè)數(shù)據(jù)后,你打算對(duì)它進(jìn)行處理,但是你又希望拷貝一份副本出來,方便數(shù)據(jù)對(duì)比和以后恢復(fù)數(shù)據(jù)。 那么這就涉及到了 JS 中對(duì)數(shù)據(jù)的深淺拷貝問題,所謂深淺拷貝,淺拷貝的意思就是,...

    ASCH 評(píng)論0 收藏0
  • 詳解js深淺復(fù)制問題

    摘要:二這么分的好處就是在于節(jié)省內(nèi)存資源,便于合理回收內(nèi)存詳解中的深淺復(fù)制有了上面的鋪墊,那么我們理解起深淺復(fù)制就變得容易的許多。 前言 對(duì)于前端開發(fā)來說,我們經(jīng)常能夠遇到的問題就是js的深淺復(fù)制問題,通常情況下我們解決這個(gè)問題的方法就是用JSON.parse(JSON.Stringify(xx))轉(zhuǎn)換或者用類似于Inmmutable這種第三方庫來進(jìn)行深復(fù)制,但是我們還是要弄懂其中原理,這樣...

    X1nFLY 評(píng)論0 收藏0
  • 詳解js深淺復(fù)制

    摘要:從而也引出了所謂的深淺復(fù)制問題。附注對(duì)于淺復(fù)制,其實(shí)還有其他的實(shí)現(xiàn)方式,比如數(shù)組中和方法,對(duì)于這些還是希望大家自己了解,本本主要針對(duì)深淺復(fù)制的實(shí)現(xiàn)原理進(jìn)行解析。 前言 在之前寫繼承的過程談到了深淺復(fù)制的問題,因?yàn)橛凶x者反映到需要解析,趁今天周末寫一篇解析,今天的主體相對(duì)之前來說理解難度低一些,篇幅可能也比較短,諸君按需閱讀即可。 從兩種數(shù)據(jù)類型說起 在js中,變量的類型可以大致分成兩種...

    Lin_YT 評(píng)論0 收藏0
  • 深入理解JS深淺拷貝

    摘要:深拷貝相比于淺拷貝速度較慢并且花銷較大。所以在賦值完成后,在棧內(nèi)存就有兩個(gè)指針指向堆內(nèi)存同一個(gè)數(shù)據(jù)。結(jié)果如下擴(kuò)展運(yùn)算符只能對(duì)一層進(jìn)行深拷貝如果拷貝的層數(shù)超過了一層的話,那么就會(huì)進(jìn)行淺拷貝那么我們可以看到和展開原算符對(duì)于深淺拷貝的結(jié)果是一樣。 JS中數(shù)據(jù)類型 基本數(shù)據(jù)類型: undefined、null、Boolean、Number、String和Symbol(ES6) 引用數(shù)據(jù)類型:...

    JackJiang 評(píng)論0 收藏0
  • 復(fù)習(xí)Javascript專題(四):js中的深淺拷貝

    摘要:基本數(shù)據(jù)類型的復(fù)制很簡(jiǎn)單,就是賦值操作,所以深淺拷貝也是針對(duì),這類引用類型數(shù)據(jù)。它會(huì)拋棄對(duì)象的。另外,查資料過程中還看到這么一個(gè)詞結(jié)構(gòu)化克隆算法還有這一篇資料也有參考,也寫得比較詳細(xì)了的深淺拷貝 基本數(shù)據(jù)類型的復(fù)制很簡(jiǎn)單,就是賦值操作,所以深淺拷貝也是針對(duì)Object,Array這類引用類型數(shù)據(jù)。 淺拷貝對(duì)于字符串來說,是值的復(fù)制,而對(duì)于對(duì)象來說則是對(duì)對(duì)象地址的復(fù)制;而深拷貝的話,它不...

    MobService 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<