此篇會介紹 ES6 新增的展開運算子 Spread Operator 的兩種類型。
展開運算子(Spread Operator)
MDN:The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) or multiple variables (for destructuring assignment) are expected.
白話文:就是將函式中 參數(arguments)
或 陣列中元素(elements)
,透過迭代(iterable)重新組成一個新的變數。
語法:
- 在需要展開的變數前方加上三個點
...
myFunction(a, ...iterableObj, b) |
1 | let number = [1, 2, 3]; |
Tip
- 展開運算子如果直接用在物件上會拋出錯誤,因為展開運算子只能用於具有索引和
length
屬性的物件。
1 | let obj = { a: 1, b: 2 }; |
常見應用
下面會演示幾種常見應用。
函式將陣列拆開當作獨立引數傳入到式中
1 | function foo(a, b, c) { |
合併陣列
1 | let arr1 = [1, 2, 3]; |
淺拷貝陣列並添加新的參數
1 | let arr1 = [1, 2, 3]; |
DOM 物件轉陣列
1 | const list = document.getElementsByTagName('body'); |
字串轉陣列
1 | let string = 'hello'; |
淺拷貝物件
1 | let obj = { a: 1, b: 2 }; |
其餘運算子 Rest Operator
在函式宣告中的最後一個參數加上 ...
,會稱其為「其餘運算子(Rest Operator)」,它與展開運算子效果上剛好完全相反,其餘運算子是把許多的參數組和成一個陣列。
MDN:將函式固定參數數量變為可變參數。
語法:
- 在不確定參數數量的地方,使用上三個點
...args
來接收剩餘全部參數。
function f(a, b, ...theArgs) { |
1 | function foo(...args) { |
Tip
- 如果在箭頭函式使用其餘運算子,即使函式只有一個參數也
必須
加上小括號。
1 | let sumAll = (...number) => number.reduce((total, next) => total + next); |
補這個是因為,箭頭函式特性當參數只有一個時,可以把參數的小括號省略。(箭頭函式介紹可以參考這篇文章)
conclusion
- 展開運算子如果直接用在物件上會拋出錯誤,因為展開運算子只能用於具有索引和 length 屬性的物件。
- 如果在箭頭函式使用其餘運算子,即使函式只有一個參數也
必須
加上小括號。
物件中的類似語法並不是 ES6 新增的特性
Object Rest/Spread Properties for ECMAScript proposal (ES2018)
1 | const obj1 = { foo: 'bar', x: 42 }; |
關於名詞不統一
- 在ECMAScript 上使用的是
SpreadElement
與rest parameter
,並且沒有一個完整的章節介紹,而是散落在各章節中。 - 在 MDN 上是用
Spread operator
與Spread syntax
(標題是 syntax,網址是 operator)、Rest operator
、Rest parameters
(標題是parameters
,網址是 operator)。