Shallow clone 又稱淺複製,淺複製是將一個物件的 第一層屬性 複製到另一個物件上,讓兩個物件擁有相同的第一層屬性。這意味著當屬性是基本型別(如字串、數字、布林值等)時,它會複製其值;但當屬性是 引用型別(如物件、陣列、函式等)時,它只會複製該屬性的記憶體位址(reference),不會真正複製其內部內容。因此,如果引用型別的屬性在某一個物件中被修改,另一個物件中的同一屬性也會受到影響。
const memberInfo = {
id: 120,
name: "Andy",
isVip: false,
birthday: "1996/01/12",
hobbies: ["Photography", "Cooking", "Painting"],
};
const copyBySpread = { ...memberInfo }; //使用 spread 語法複製物件 memberInfo
console.log("copyBySpread === memberInfo", copyBySpread === memberInfo); //false
//可以確定 copyBySpread 與 memberInfo 這兩個物件的 reference 不同的
console.log(
"copyBySpread.hobbies === memberInfo.hobbies",
copyBySpread.hobbies === memberInfo.hobbies,
); //true
//memberInfo 中的 hobbies 屬性是一個陣列,物件的比對 === 就是其記憶體的位址,
//可以確定 copyBySpread 與 memberInfo 這兩個物件的 hobbies 這個屬性都是指向同一個 reference 的,
//所以當修改 copyBySpread.hobbies 的內容時,也會影響到 memberInfo.hobbies 的內容。
那如果想要淺複製物件內巢狀的物件或物件可以這麼做:
const copyNestBySpread = {
...memberInfo, //先淺複製 memberInfo 第一層的屬性
hobbies: [...memberInfo.hobbies], //在 copyNestBySpread 物件中新增 hobbies 屬性,然後將 memberInfo.hobbies 陣列淺複製到 copyNestBySpread.hobbies
};
//這時候再次檢查 copyNestBySpread.hobbies 與 memberInfo.hobbies 的 reference 是否相同
console.log(
"copyNestBySpread.hobbies === memberInfo.hobbies",
copyNestBySpread.hobbies === memberInfo.hobbies,
); //false
// 這時候修改 copyNestBySpread.hobbies 的內容就不會影響到 memberInfo.hobbies 的內容
使用 spread 展開運算符的好處是語法相對簡潔,讓程式碼容易閱讀。
const memberInfo = {
id: 120,
name: "Andy",
isVip: false,
birthday: "1996/01/12",
hobbies: ["Photography", "Cooking", "Painting"],
};
const copyByAssign = Object.assign({}, memberInfo); ////使用 Object.assign() 複製物件 memberInfo
console.log("copyByAssign === memberInfo", copyByAssign === memberInfo); //false
console.log(
"copyByAssign.hobbies === memberInfo.hobbies",
copyByAssign.hobbies === memberInfo.hobbies,
); //true