這篇文章的標題來自我在Quora上被要求回答的一個問題。下面是我試圖解釋JavaScript中三個點的做用。但願這對於未來有相同問題的人來講能夠消除圍繞這個概念的迷霧。web
假設您有如下對象:數組
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對象並獲取其全部屬性,而後用咱們傳遞的屬性覆蓋現有屬性。能夠將這種傳播視爲逐個提取全部單個屬性並將它們傳遞給新對象。this
在這種狀況下,因爲咱們在擴展運算符啓動後指定了fullName和網站屬性,所以JavaScript引擎知道咱們要覆蓋來自原始對象的那些屬性的原始值。prototype
除了傳播鍵和值以外,運算符不會傳播索引(index)和值。與對象傳播不一樣的是,你不會有重複的屬性,由於這是JavaScript對象的工做方式(你不能擁有一個具備兩個fullName屬性的對象),若是你計劃實現相似的東西,那麼對於數組你最終可能會有重複的值到咱們的對象示例。rest
這意味着下面的代碼將致使您擁有包含重複元素的數組。code
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操做符使開發人員可以建立能夠獲取無限數量的參數的函數,也稱爲變量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運算符。