用 spread 複製物件,改了巢狀的東西結果原本也被改⋯⋯
淺拷貝只複製第一層,這就是代價。
這篇建立在 by reference 的概念上,還不熟的話可以先看這篇。
淺拷貝
只複製第一層,巢狀物件還是共用同一個參考。
spread 和 Object.assign 都是淺拷貝:
js
const original = { name: 'Yuzu', address: { city: 'Taipei' } };
const shallow = { ...original };
shallow.name = 'Mochi'; // ✅ 不影響 original
shallow.address.city = 'Osaka'; // ❌ original.address.city 也變了
console.log(original.name); // 'Yuzu'
console.log(original.address.city); // 'Osaka'
name 是 string(by value),所以安全。
address 是 object(by reference),所以還是同一個。
深拷貝
完整複製所有層,兩個物件完全獨立。
現代瀏覽器原生支援 structuredClone:
const original = { name: 'Yuzu', address: { city: 'Taipei' } };
const deep = structuredClone(original);
deep.address.city = 'Osaka';
console.log(original.address.city); // 'Taipei' ✅
老專案常見但有限制(不支援 function、Date 等):
const deep = JSON.parse(JSON.stringify(original));