JS深拷貝的實(shí)現(xiàn)

在面試中經(jīng)常問到深拷貝的實(shí)現(xiàn),但由于在項(xiàng)目中都是用網(wǎng)上現(xiàn)成的或者依賴各種函數(shù)庫完成。偶爾在回答的時(shí)候就腦袋短路了,現(xiàn)在有時(shí)間了就簡(jiǎn)單整理了一下。

先說一下自己用過的一些方法

  1. 通過 JSON 對(duì)象實(shí)現(xiàn)深拷貝
//通過js的內(nèi)置對(duì)象JSON來進(jìn)行數(shù)組對(duì)象的深拷貝
function deepClone(obj) {
    var _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
    return objClone;
}

缺陷:它會(huì)拋棄對(duì)象的constructor,深拷貝之后,不管這個(gè)對(duì)象原來的構(gòu)造函數(shù)是什么,在深拷貝之后都會(huì)變成Object;這種方法能正確處理的對(duì)象只有 Number, String, Boolean, Array, 扁平對(duì)象,也就是說,只有可以轉(zhuǎn)成JSON格式的對(duì)象才可以這樣用,像function沒辦法轉(zhuǎn)成JSON;

  1. lodash函數(shù)庫實(shí)現(xiàn)深拷貝
lodash是一個(gè)很優(yōu)秀的函數(shù)庫,提供了 lodash.cloneDeep()實(shí)現(xiàn)深拷貝
  1. Object.assign()拷貝
當(dāng)對(duì)象中只有一級(jí)屬性,沒有二級(jí)屬性的時(shí)候,此方法為深拷貝,但是對(duì)象中有對(duì)象的時(shí)候,此方法,在二級(jí)屬性以后就是淺拷貝

上面這幾種方法都能簡(jiǎn)單的實(shí)現(xiàn)深拷貝,但是各有各的特點(diǎn),也有各方面的缺點(diǎn)。所以就有了下面作者自己的實(shí)現(xiàn)方式。

function deepClone(value,hash = new WeakMap){  // WeakMap弱引用,不要用map
    if(value == null){
        return null;
    }
    if(value instanceof RegExp){
        return new RegExp(value);
    }
    if(value instanceof Date){
        return new Date(value);
    }
    //函數(shù)不需要拷貝
    if(typeof value != 'object') return value;

    let obj = new value.constructor;  //判斷是對(duì)象還是數(shù)組 并且new

    if(hash.get(value)){  //如果這個(gè)對(duì)象拷貝過了 就返回那個(gè)拷貝的結(jié)果就可以了
        return hash.get(value);
    }

    hash.set(value,obj);   //如果這個(gè)對(duì)象沒有拷貝過 就添加到WeakMap里面

    for (let key in value) {  // in 會(huì)遍歷當(dāng)前對(duì)象上面的屬性和__proto__指代的屬性
        if (value.hasOwnProperty(key)) {
            // 如果值還有可能是對(duì)象 就利用遞歸繼續(xù)拷貝
            obj[key] = deepClone(value[key],hash)
        }
    }
    return obj;
    
    //區(qū)分對(duì)象和數(shù)組 Object.prototype.tostring.call
}

let o = {name: '123'};
console.log(deepClone(o))
最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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