學習 ECMAScript/JavaScript 6 - 新函數語法 - Arrow function, Rest and Spread parameters, Default value
ECMAScript/JavaScript 6 為函數定義與操作增加了一些新的語法,在此一併介紹。它們分別是:
- 匿名函數箭形語法 (箭頭函數): Arrow functions
- 不定數量參數: Rest parameters / Spread parameters
- 指定參數預設值: Parameters default value
Arrow functions 箭頭函數
ECMAScript/JavaScript 傳統的匿名函數定義語法只是去掉一般函數定義中的名稱部份。 ES6 則從 C# 借來了新的匿名函數語法,讓設計者少打一些字。並稱此新語法為 Arrow functions (箭頭函數)。因為我本來就會 C# ,這個 ES6 的新語法在我眼中反而有著熟悉感。
=>
的箭頭形狀稱呼這項新語法。我叫它匿名函數箭形語法。一般稱為箭頭函數。
箭形函數有一點和傳統函數不同,那就是箭形函數內部不會配置一個代表自己的 this 。如果你在箭形語法中使用了 this ,它指的是包覆這個箭形語法敘述區塊的函數,也就是外面的 this 。所以箭形語法基本上不能動態地被指定為個體方法。
… 不定數量參數
ES6 為不定數量參數的使用場合增加了一個 ...symbol
新語法。但這個新語法依使用場合分別有兩個不同的意義。
- 函數定義參數清單時,稱為 Rest parameters (其餘參數)。
- 調用函數傳遞參數時,稱為 Spread parameters (攤開參數)。
我在 COSCUP 2014 遊記 中已記述了一些 ...
的內容。
Rest parameters
在 ECMAScript/JavaScript3 時代,就已經定義了基本的不定數量參數項目,它叫做 Arguments 。 每當函數被調用時,其內部都會配置一個型態為 Arguments 的 arguments 變數,用於存放傳給這個函數的所有參數內容。它以 key/value 形式存放參數清單項目,可用 arguments[n]
的方式取得參數。並具有 length 屬性。
現在 ES6 增加了 Reset parameters (其餘參數)功能,讓使用者自己命名了。而 Rest parameters 和 arguments 差別在於 arguments 存有全部參數清單項目,而 Rest parameters 只包含了沒有單獨賦於名稱的其餘參數。
其餘參數顧名思義,必須是函數定義的參數清單內容最後一項。而 ...
後緊跟著的符號名稱,就是函數內儲存其餘參數的陣列名稱。
arguments 的行為看起來很像陣列,其實不是。而 rest parameters 就真的是陣列了。
Firefox 30 不允許 rest parameter 和 arugments 同時使用。在一個宣告了 rest parameters 的函數中,若是使用了 arugments 會被視為語法錯誤。
以下示範其餘參數與 arguments 的使用方式與差異。
Spread parameters
Spread parameters (攤開參數) 意指調用函數時,將緊跟著 ...
的那個集合內容,攤開成獨自的參數(攤開對象必須是陣列或迭代器)。而且它可以放在參數列的任何位置。
攤開參數是一個很實用的改變。在 ECMAScript/JavaScript5 以前,要把一組參數攤開傳給函數時,只能用 apply()
。 但 apply()
同時也有改變函數內部 this 指涉對象的效果,而且這才是它的主要目的,故語意不清晰。對單純想要使用函數的人來說,這是個麻煩的副作用。
對 library/framework 的設計者來說,攤開參數提供了很多設計與使用上的彈性。
… 運算子使用技巧
除了「Reset parameters (其餘參數)」和「Spread parameters (攤開參數)」這兩個一般用法, ...
運算子還可以用於陣列/個體的複製與合併。
Parameters default value 指定參數預設值
ECMAScript/JavaScript 原本就規定沒有傳值的參數,默認其值為 undefined。現在, ES6 允許使用者自己決定參數的預設值。它的語法很簡單,就是函數定義時,在參數後面加上 =預設值
。而且預設值可以使用變數或另一個參數。
另外,在其他提供指定參數預設值功能的程式語言中,多數限定帶有預設值的參數必須放在參數清單後半部,不可將有預設值與無預設值的參數夾雜一起。但是 ECMAScript/JavaScript 無此限制。因為 ECMAScript/JavaScript 隱含規定每一個參數都有預設值 undefined 。
注意,調用函數時,就算使用者傳遞的參數數目少於參數清單定義的數目,參數值仍然會由左到右依序指派,並不會跳過帶有自定預設值的參數項。承上例的 xyz()
,使用時:
指定參數預設值大幅簡化了設計函數時的初始工作。以往設計函數時,如果希望函數的某些參數可在省略不傳的情形就套用指定值的話,我們要在函數開頭寫上一堆 if (y == undefined) y =1
之類的程式碼。現在只要在參數清單中直接指定即可,語意更明確。
相關文章
- ES6 In Depth: Arrow functions
- ES6 In Depth: Rest parameters and Defaults
- COSCUP 2014 遊記
- Functional enhancements in ECMAScript 6
- 石頭閒語: ECMAScript/JavaScript 6 - Template strings
- 石頭閒語: ECMAScript/JavaScript 6 - Symbol
- 石頭閒語: ECMAScript/JavaScript 6 - for-of 與 iterator。
- 石頭閒語: ECMAScript/JavaScript 6 - Generator
- 石頭閒語: ECMAScript/JavaScript 6 - 新函數語法 - Arrow functions, Rest and Spread parameters, Default value
- 石頭閒語: ECMAScript/JavaScript 6 - Destructuring
- 石頭閒語: ECMAScript/JavaScript 6 - var, let 和 const
- 石頭閒語: ECMAScript/JavaScript 6 - Proxy 和 Reflect
- 石頭閒語: ECMAScript/JavaScript 6 - Class
- 石頭閒語: ECMAScript/JavaScript 6 - 語法補遺
- 石頭閒語: ECMAScript/JavaScript 6 - Promise