ES6 對象解構賦值(淺拷貝 VS 深拷貝)


對象的擴展運算符(...)用於取出參數對象的所有可遍歷屬性,拷貝到當前對象之中。

拷貝對象

let aa = {
	age: 18,
	name: 'aaa'
}

 
let bb = {...aa};
console.log(bb);  // {age: 18, name: "aaa"}

合並對象

擴展運算符(...)可以用於合並兩個對象

let aa = {
	age: 18,
	name: 'aaa'
} 

let bb = {
	sex: '男'
}
  
let cc = {...aa, ...bb}; 


// 等同於: 
// let cc = Object.assign({}, aa, bb);


console.log(cc); // {age: 18, name: "aaa", sex: "男"}

拷貝並修改對象

在擴展運算符后面,加上自定義的屬性,則擴展運算符內部的同名屬性會被覆蓋掉。

let aa = {
	age: 18,
	name: 'aaa'
}
 
let dd = {...aa, name: 'ddd'};
 

// 等同於: 
// let dd = {...aa, ...{name: 'ddd'}};
// let dd = Object.assign({}, aa, { name: 'ddd'});



console.log(dd); // {age: 18, name: "ddd"}

一般,在 redux 中修改 state 時,會用解構賦值的方法。

但是,解構后得到的新對象,相對於老對象,是淺拷貝,還是深拷貝?

例如,下面肯定是引用賦值:

let aa = {
	age: 18,
	name: 'aaa'
}

let bb = aa;
bb.age = 22;

console.log(aa.age); // 22

上面, 對象 bb 是 aa 的一個引用賦值。那么,如果使用解構賦值得到 bb 呢:

let aa = {
	age: 18,
	name: 'aaa'
}

let bb = {...aa};
bb.age = 22;

console.log(aa.age); // 18
  • 可見,改變 bb 的屬性 age 的值,並不會改變對象 aa 的屬性的 age 的值,所以,上面的例子bb是aa的一份拷貝
  • 但是,這個拷貝是只有一層的淺拷貝,還是深拷貝?
let aa = {
	age: 18,
	name: 'aaa',
	address: {
		city: 'shanghai'
	}
}

let bb = {...aa};
bb.address.city = 'shenzhen';

console.log(aa.address.city);  // shenzhen

可見,aa 解構賦值到新對象 bb,只是進行了一層淺拷貝,對象 bb 中的屬性(address)的屬性(city)還是對象 aa 中屬性的屬性的引用。

如果像拷貝 aa 中的 city 屬性,可以像下面處理:

let aa = {
	age: 18,
	name: 'aaa',
	address: {
		city: 'shanghai'
	}
}

let bb = {
	...aa,
	address: {...aa.address}
};

bb.address.city = 'shenzhen';

console.log(aa.address.city);  // shanghai


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM