箭頭函數表示式 (Arrow function expression,也是所謂的 fat arrow function) 比起一般的函數表示式擁有更短的語法以及詞彙上綁定 this 變數,所有的箭頭函數都是無名函數 (anonymous function).
基本語法
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// 等於 : => { return expression; }
// 只有一個參數時,括號才能不加:
(singleParam) => { statements }
singleParam => { statements }
//若無參數,就一定要加括號:
() => { statements }
詳細語法範例請參照這裡。
param
- 參數名稱。多個參數以()包住,如不需要參數則以
()
表示, 如只有一個參數可以省略括弧 (如foo => 1
)。 statements or expression
- 當有多個陳述 (statement) 需用 { } 框住,當只有一個陳述則不需;其中表示式 (Expression) 最後也會是箭頭函數的返回值。
說明
箭頭函數有兩個重要的特性:更短的函數寫法與 this 變數綁定。
更短的函數寫法
比較一般寫法和箭頭函數寫法;In some functional patterns, shorter functions are welcome. Compare:
var a = [
"Hydrogen",
"Helium",
"Lithium",
"Beryllium"
];
var a2 = a.map(function(s){ return s.length });
var a3 = a.map( s => s.length );
this 變數綁定
在過去,函數的 this 變數在不同狀況下一直指向不同值 (例如當建構子呼叫時指向的是新建構的物件、undefined 在 strict 模式、當以物件方法呼叫時只向呼叫物件),這樣的特性對物件導向程式設計來說其實相當麻煩。
function Person() {
// The Person() constructor defines `this`
as itself.
this.age = 0;
setInterval(function growUp() {
// In nonstrict mode, the growUp() function defines `this`
// as the global object, which is different from the `this`
// defined by the Person() constructor.
this.age++;
}, 1000);
}
var p = new Person();
為了解決這個問題,常見的方法是利用 closure 將 this 變數存入另一個變數之中:
function Person() {
var self = this; // Some choose `that` instead of `self`.
// Choose one and be consistent.
self.age = 0;
setInterval(function growUp() {
// The callback refers to the `self` variable of which
// the value is the expected object.
self.age++;
}, 1000);
}
或者是,透過綁定函數的作法來綁定 this 變數到 growUp 函數。
不過現在箭頭函數會自動將 this 變數綁定到其定義時所在的物件,如下所示:
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| properly refers to the person object
}, 1000);
}
var p = new Person();
和 Strict 模式
由於 this 變數具有詞彙上綁定義意,所以 strict 模式的宣告對 this 的作用將被忽略。
var f = () => {'use strict'; return this};
f() === window; // or the global object
但其於 strict 模式作用仍存在。
和 call 與 apply 函數
由於 this 變數已被綁定,所以透過 call 或 apply 呼叫箭頭函數只能傳入參數但無法改變 this:
var adder = {
base : 1,
add : function(a) {
var f = v => v + this.base;
return f(a);
},
addThruCall: function(a) {
var f = v => v + this.base;
var b = {
base : 2
};
return f.call(b, a);
}
};
console.log(adder.add(1)); // This would log to 2
console.log(adder.addThruCall(1)); // This would log to 2 still
Examples
// An empty arrow function returns undefined
let empty = () => {};
(() => "foobar")() // returns "foobar"
var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10
let max = (a, b) => a > b ? a : b;
// Easy array filtering, mapping, ...
var arr = [5, 6, 13, 0, 1, 18, 23];
var sum = arr.reduce((a, b) => a + b); // 66
var even = arr.filter(v => v % 2 == 0); // [6, 0, 18]
var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46]
規範標準
Specification | Status | Comment |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Arrow Function Definitions' in that specification. | Standard | Initial definition. |
瀏覽器相容性
Firefox 特定註記
- 在 Firefox 24 前,strict mode 會隨著箭頭函數定義而生效,但之後已取消,明白宣告 strict mode 是需要的。
- 箭頭函數和 Firefox3 加入、非標準的 Expression Closures (詳細資訊: Javascript 1.8) 有所不同,針對 Expression Closures 並無綁定 this 變數。
- 在 Firefox 39 前, 單行終結符號 (
\n
) 錯誤地必允許在箭頭函數,現在這項錯誤已經修正以符合 ES6 標準,類似程式碼如() \n => {}
將導致SyntaxError
錯誤。
文件標籤與貢獻者
此頁面的貢獻者: linjimmy168, foxbrush