今天看到了你必須收藏的 ES6 語法密糖 – Spread Operator 技巧,這篇文章,收穫很多,同時也想起來
...
也有一些操作物件的用法,總結了一下。
在 ECMAScript 2018 中 Spread Operator 增加了對物件的支援,使得它的應用更為廣泛,本文重點介紹如何將它與 Object 一起使用以及與 Object.assgin
的區別。
可以通過BABEL,檢視示例程式碼 babel 編譯後的結果。
...
解構賦值
除去已經宣告的屬性,剩餘的所有屬性都會賦給 ...
後的屬性名
let {
x, ...y
} = {
x: 1, y: 2, a: 3, b: 4
};
console.log(x);
// 1console.log(y);
// {y: 2, a: 3, b: 4
}複製程式碼
...
刪除屬性值
利用 ...
來刪除物件中的某一個屬性
let {
x: deleted, ...y
} = {
x: 1, y: 2, a: 3, b: 4
};
console.log(y);
// {y: 2, a: 3, b: 4
}複製程式碼
...
複製物件
在 JavaScript 中,有一個常見賦值語法如下
var cat = {
age: 4
};
var kitten = cat;
kitten.age = 1;
複製程式碼
此時, cat
和 kitten
引用同一個物件,如果修改了 kitten
的屬性,相應的 cat
也會發生變化。
console.log(kitten.age);
// 1console.log(cat.age);
// 1 <
-- problem!複製程式碼
使用 Spread Operator 可以輕鬆地建立一個具有現有物件的所有相同屬性的新物件。
const cat = {
age: 4
};
const kitten = {
...cat
};
// <
-- changedkitten.age = 1;
console.log(kitten.age);
// 1console.log(cat.age);
// 4 <
-- fixed!複製程式碼
但是,利用 Spread Operator 去賦值物件,只能完成淺複製,也就是說利用 ...
去複製物件時,並不能遞迴地複製所有層級。
const cat = {
age: 4, toys: ["mouse", "catnip"]
};
const kitten = {
...cat
};
// const kitten = Object.assign({
}, cat);
<
-- same resultkitten.toys[1] = "yarn";
console.log(kitten.toys);
// ["mouse", "yarn"]console.log(cat.toys);
// ["mouse", "yarn"] <
-- problem!複製程式碼
...
擴充套件物件
利用 ...
來擴充物件,就是將新屬性新增到使用 Spread Operator 建立的物件上
const cat = {
legs: 4
};
const dog = {
...cat, sound: "woof"
};
console.log(cat);
// {
legs: 4
}console.log(dog);
// {
legs: 4, sound: "woof"
}複製程式碼
同樣,可以看到 cat
物件未被更改,但新 dog
物件具有來自 cat
的 legs
屬性以及新 sound
屬性,如果sound
已經存在的話,則會覆蓋。
const cat = {
legs: 4, sound: "meow"
};
const dog = {
...cat, sound: "woof"
};
console.log(cat);
// {
legs: 4, sound: "meow"
}console.log(dog);
// {
legs: 4, sound: "woof"
}複製程式碼
但是,使用 ...
擴充物件時,要注意行順序,也就是
const cat = {
legs: 4, sound: "meow"
};
const dog = {
sound: "woof", ...cat
};
console.log(cat);
// {
legs: 4, sound: "meow"
}console.log(dog);
// {
legs: 4, sound: "meow"
}複製程式碼
上述 ...cat
將 sound: "woof"
改寫為 sound: "meow"
。
...
與 Object.assign
的區別
在上述利用 ...
處理物件的過程中,會發現 ...
有些時候與 Object.assgin
的操作近乎與等價的,那麼他們具體的區別是什麼。
Object.assign()
函式會觸發 setters,而展開語法則不會,具體見JS: Object.assign() Vs Spread Operator。