淺談JavaScript 中深拷貝實現的方法

相信人不少學習js的過程當中都踩了深拷貝和淺拷貝的坑,深拷貝和淺拷貝的區別我就再也不贅述了,今天我來寫一下我本身實現深拷貝的各類方法。
比較簡單的拷貝方式能夠借用瀏覽器的Json對象去實現,先把對象轉化爲json字符串,在解析回對象實現深拷貝。具體代碼就是JSON.parse(JSON.stringify(target));可是這種比較hack的方法總歸不是正途,如今我就來貼兩種我本身寫的深拷貝代碼。json

function deepClone(currobj){
    if(typeof currobj !== 'object'){
        return currobj;
    }
    if(currobj instanceof Array){
        var newobj = [];
    }else{
        var newobj = {}
    }
    for(var key in currobj){
        if(typeof currobj[key] !== 'object'){
            newobj[key] = currobj[key];
        }else{
            newobj[key] = deepClone(currobj[key])    
        }
    }
    return newobj
}

第一種天然就是遞歸,遍歷對象的每個屬性而後賦值到新對象了,如果有深層次嵌套的對象,遞歸執行函數。jq中的深拷貝也是用相似方法實現。數組

function deepClone(currobj){
        if(typeof currobj !== 'object'){
            return currobj;
        }
        if(currobj instanceof Array){
            var newobj = [];
        }else{
            var newobj = {}
        }
        var currQue = [currobj], newQue = [newobj];
        while(currQue.length){
            var obj1 = currQue.shift(),obj2 = newQue.shift();
            for(var key in obj1){
                if(typeof obj1[key] !== 'object'){
                    obj2[key] = obj1[key];
                }else{
                    if(obj1[key] instanceof Array ){
                        obj2[key] = [];
                    }else{
                        obj2[key] = {}
                    };
                    currQue.push(obj1[key]);
                    newQue.push(obj2[key]);
                }
            }
        }
        return newobj;
    };

上一種遞歸的方式容易引發內存溢出,特別是對一個比較複雜,層級很深的對象進行深拷貝。因此第二種方法是用循環去拷貝次級的對象,用兩個隊列去保存須要拷貝的對象和拷貝目標,利用淺拷貝的原理實現了深拷貝。瀏覽器

可是有時候對象會存在子屬性指向自身的問題,造成對象環,我這暫時尚未考慮到。

忽然看到本身這篇文章,其實對象環的問題只須要別將舊數組出棧就好了具體代碼:函數

function deepClone(currobj){
    if(typeof currobj !== 'object'){
        return currobj;
    }
    if(currobj instanceof Array){
        var newobj = [];
    }else{
        var newobj = {}
    }
    var currQue = [currobj], newQue = [newobj], i = 0;
    while(i <= currQue.length - 1){
        var obj1 = currQue[i++],obj2 = newQue.shift();
        for(var key in obj1){
            if(typeof obj1[key] !== 'object'){
                obj2[key] = obj1[key];
            }else{
                if(currQue.includes(obj1[key])){
                    obj2[key] = obj1[key];
                    continue;
                }
                if(obj1[key] instanceof Array ){
                    obj2[key] = [];
                }else{
                    obj2[key] = {}
                };
                currQue.push(obj1[key]);
                newQue.push(obj2[key]);
            }
        }
    }
    return newobj;
};
相關文章
相關標籤/搜索