這篇文章的標題來自我在Quora上被要求回答的一個問題。下面是我試圖解釋JavaScript中三個點的作用。希望這對於將來有相同問題的人來說可以消除圍繞這個概念的迷霧。
陣列/物件擴充套件運算子
假設您有以下物件:
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)操作。就速度和記憶體使用而言,這表現不佳並且不優雅。這樣的程式碼,容易讓你的初級水平的同事感到困惑。
這應該是您需要了解的所有內容,以便在JavaScript中使用rest / spread運算子。