Json對象深拷貝

1、淺拷貝

        對於一個引用類型,如果直接將它賦值給另一個對象,只是將引用地址賦值給新對象,修改一個對象另一個也會被更改。 

        例:

var user = {
    code:'0001',
    name:'張三'
};
var user2 = user;
user2.name = '李四';
console.log(user);
console.log(user2);

    結果:

    

   修改user2的name屬性,user的name屬性也被修改了。

       當需要複製後的對象獨立於原對象,就要用深拷貝。   

2、深拷貝

        深拷貝不是將原對象的引用賦值給新對象,而是新建一個對象,引用地址與原對象引用地址不同,再將原對象屬性拷貝到新對象中。有兩種常用方式實現引用類型的深拷貝,但都只適用於特定情況。

        1.Object.assign()方法。

        ES6提供了Object.assign()方法用於深拷貝。

例:

var Jack ={
    code:'0001',
    name:'張三',
    assing:function () {
        alert('張三簽到');
    },
    car:{
        name:'路虎',
        type:'SVR'
    }
}

var Tom = Object.assign({},Jack);
Tom.name = '趙四';
console.log(Jack);
console.log(Tom);
Tom.car.name='寶馬';
console.log(Jack);
console.log(Tom);

結果:


可以看到改變Tom.name屬性,Jack的name屬性並不會被更改,成功實現了深拷貝。

但是改變Tome.car.name,Jack.car.name依然會被更改。

這是因爲Object.assign()方法實現只實現了一層屬性的深拷貝,屬性值如果是對象,該對象並不會被深拷貝。

    2.Json.parse(Json.stringify(obj))方式

例:

var Alex = JSON.parse(JSON.stringify(Jack));
Alex.name='王五';
Alex.car.name='勞斯萊斯';
console.log(Jack);
console.log(Alex);

結果:

    

該方法成功實現了嵌套屬性的深拷貝,但是原對象中的assign()方法丟失了。

這是因爲JSON.stringify()方法將對象轉化爲字符串,但只會處理簡單屬性和簡單屬性數組,constructor屬性丟失了。

例:

console.log(JSON.stringify(Jack));
result:{"code":"0001","name":"張三","car":{"name":"寶馬","type":"SVR"}}

因此,除非對象只有簡單屬性,沒有constructor信息,才能使用Json.parse(Json.stringify(obj))做深拷貝。

    3.自定義完全深拷貝方法

遞歸遍歷對象所有屬性。

function deepClone(obj) {
    var type = Object.prototype.toString.call(obj);  //通過原型對象獲取對象類型
    var newObj;
    if(type ==='[object Array]'){
        //數組
        newObj =[];
        if(obj.length >0){
            for(var x=0;x<obj.length;x++){
                newObj.push(deepClone(obj[x]));
            }
        }
    }else if(type==='[object Object]'){
        //對象
        newObj = {};
        for(var x in obj) {
            newObj[x] = deepClone(obj[x]);
        }
    }else{
        //基本類型和方法可以直接賦值
        newObj = obj;
    }
    return newObj;
}

var a1 = [1,{name:'cc',test:()=>{}},3];
var a2 = deepClone(a1);
a2[1].name = '121';
console.log(a1);
console.log(a2); 

結果:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章