數組/對象擴展運算符
假設您有以下對象:
const adrian = {
fullName: 'Adrian Oprea',
occupation: 'Software developer',
age: 31,
website: 'https://oprea.rocks'
};
假設您要創建一個具有不同名稱和網站但具有相同職業和年齡的新對象(人)。
您可以通過僅指定所需的屬性來執行此操作,並使用擴展運算符來完成其餘操作,如下所示:
const bill = {
...adrian,
fullName: 'Bill Gates',
website: 'https://microsoft.com'
};
上面代碼的作用是遍佈adrian對象並獲取其所有屬性,然後用我們傳遞的屬性覆蓋現有屬性。可以將這種傳播視爲逐個提取所有單個屬性並將它們傳遞給新對象。
在這種情況下,由於我們在擴展運算符啓動後指定了fullName和網站屬性,因此JavaScript引擎知道我們要覆蓋來自原始對象的那些屬性的原始值。
這與陣列類似。除了傳播鍵和值之外,運算符不會傳播索引(index)和值。與對象傳播不同的是,你不會有重複的屬性,因爲這是JavaScript對象的工作方式(你不能擁有一個具有兩個fullName屬性的對象),如果你計劃實現類似的東西,那麼對於數組你最終可能會有重複的值到我們的對象示例。
這意味着下面的代碼將導致您擁有包含重複元素的數組。
const numbers1 = [1, 2, 3, 4, 5];
const numbers2 = [ ...numbers1, 1, 2, 6,7,8]; // this will be [1, 2, 3, 4, 5, 1, 2, 6, 7, 8]
可以把它想象成Array.prototype.concat的替代品.
rest運算符
使用函數的參數時,無論是完全替換參數還是與函數的參數一起替換參數,這三個點也稱爲rest運算符。
當像這樣使用它時,rest操作符使開發人員能夠創建可以獲取無限數量的參數的函數,也稱爲變量arity或可變函數。
這是這種功能最簡單的例子。假設您要創建一個計算其所有參數之和的函數。請注意,它不是兩個,三個或四個數字的總和,而是函數作爲參數接收的所有數字的總和。
這是一個簡單的實現,使用rest運算符
function sum(...numbers) {
return numbers.reduce((accumulator, current) => {
return accumulator += current
});
};
sum(1,2) // 3
sum(1,2,3,4,5) // 15
最簡單的解釋是,rest運算符接收函數接收的參數並將它們轉儲到以後可以使用的實數數組中。
你可能會覺得,你可以通過請求用戶傳遞一組數字來完成此操作。這在技術上是可行的,但是這樣的用戶體驗很差,因爲用戶希望用普通數字而不是數字列表來調用sum函數。
您可能還認爲可以使用arguments數組。這也是事實,但要小心,參數不是真正的數組,而是類似數組的對象(具有length屬性的對象)。對於我們的sum函數的第一次調用,在前面的例子中,它實際上看起來像這樣:
{
'0': 1,
'1': 2,
'length': 2
}
要操作此對象並在其上使用數組方法,例如reduce,從我之前的示例中,您必須執行Array.prototype.slice.call(arguments,0)操作。就速度和內存使用而言,這表現不佳並且不優雅。這樣的代碼,容易讓你的初級水平的同事感到困惑。