Javascript對象的深淺拷貝

開門見山,有人叫對象的複製爲深複製淺複製,也有人叫深拷貝淺拷貝。
其實都是copy。javascript

深拷貝(遞歸複製,複製全部層級,獨立副本,一個徹底和原來對象屬性無關的副本)
返回對象:一個。
傳入對象:一個。
條件:JSON安全的對象,能夠序列化爲JSON字符串,而且能夠解析爲新的字符串。
深拷貝算法:前端

function deepCopy(data){
    let memory = null;
    const type = Object.prototype.toString.call(data);
    if (type === "[object Array]"){
        memory = []
        for (let i=0 ;i<data.length;i++){
            memory.push(deepCopy(data[i]))
        }
    }else if (type === "[object Object]"){
        memory = {}
        Object.keys[data].forEach((key)=>{
            memory[key] = data[key]
        })
    }else{
        return data;
    }
    return memory;
}

jQuery深拷貝:
var copiedObject = jQuery.extend(true, {}, originalObject)java

es6深拷貝:
var copiedObject= JSON.parse(JSON.stringify(originalObject));git

深拷貝是遞歸複製,新複製的對象與原對象是徹底獨立的兩個對象,它們指向不一樣的內存地址,作set不會影響到對方。es6

淺拷貝(單次複製,複製最高層級,引用副本,一個基於對原對象屬性引用的副本)
返回對象:一個。
傳入對象:一個或多個。
條件:無。github

jQuery淺拷貝:
var copiedObject = jQuery.extend({}, originalObject)算法

es6淺拷貝:
var copiedObject = Object.assign({},originalObject)segmentfault

es7淺拷貝:
var copiedObject = {...originalObject}數組

淺拷貝算法:安全

function shallowCopyObj(original){
        let copy = {}
        Object.keys(original).forEach(key=>{
            copy[key] = original[key]
        })
        return copy
    }

因爲javascript的對象是存地址的,因此淺複製的對象與原對象,都指向同一個內存地址,屬於引用複製,作set會影響到對方。

實驗:
①普通屬性修改:深拷貝和淺拷貝均可以知足對象的複製。
普通屬性是指value值爲非Array,Object類型的數據類型,也就是Number,String,Boolean等基本數據類型。
緣由:基本數據類型屬於值傳遞。

var obj = {foo:1};
var deepCopyObj = JSON.parse(JSON.stringify(obj));
deepCopyObj.foo = 2;
console.log("obj.foo:",obj.foo);//1
console.log("deepCopyObj.foo:",deepCopyObj.foo);//2
var obj = {foo:1};
var shallowCopyObj = Object.assign({},obj);
shallowCopyObj.foo = 2;
console.log("obj.foo:",obj.foo);//1
console.log("shallowCopyObj.foo:",shallowCopyObj.foo);//2

②高級屬性修改:深拷貝知足對象的複製,淺拷貝影響原數組。
高級屬性是指Array,Object數據類型。
緣由:基本數據類型屬於引用傳遞。

var obj = {foo:1,bar:{baz:1}};
var deepCopyObj = JSON.parse(JSON.stringify(obj));
deepCopyObj.bar.baz = 2;
console.log("obj.bar.baz:",obj.bar.baz);//1
console.log("deepCopyObj.bar.baz:",deepCopyObj.bar.baz);//2
var obj = {foo:1,bar:{baz:1}};
var shallowCopyObj = Object.assign({},obj);
shallowCopyObj.bar.baz = 2;
console.log("obj.bar.baz:",obj.bar.baz);//2 Attention!
console.log("shallowCopyObj.bar.baz:",shallowCopyObj.bar.baz);//2

印象中const也是保持變量地址不變的操做,那麼es6中的let和const對於對象的深淺拷貝有影響嗎?

也就是將上面代碼中的var替換爲let和const。

實驗結果是let和const不會影響深淺拷貝的結果,由於let強調塊做用域,而const強調變量總體地址空間的不變性。

關於對象的深淺拷貝,暫且探索到這裏,後續有新發現再進行補充。

謝謝您的閱讀~

期待和你們交流,共同進步,歡迎你們加入我建立的與前端開發密切相關的技術討論小組:

努力成爲優秀前端工程師!

相關文章
相關標籤/搜索