Json對象的深淺拷貝

一、淺拷貝數組

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

        例:prototype

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

    

 

   修改user2的name屬性,user的name屬性也被修改了。
       當須要複製後的對象獨立於原對象,就要用深拷貝。   對象

二、深拷貝blog

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

        1.Object.assign()方法。字符串

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

例:string

 

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); 

 


結果:

相關文章
相關標籤/搜索