箭頭函數 (Arrow Function)

This is a new technology, part of the ECMAScript 2015 (ES6) standard.
This technology's specification has been finalized, but check the compatibility table for usage and implementation status in various browsers.

箭頭函數表示式 (Arrow function expression,也是所謂的 fat arrow function) 比起一般的函數表示式擁有更短的語法以及詞彙上綁定 this 變數,所有的箭頭函數都是無名函數 (anonymous function).

基本語法

(param1param2, …, paramN) => { statements } 
(param1param2, …, 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",
  "Beryl­lium"
];

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 變數已被綁定,所以透過 callapply 呼叫箭頭函數只能傳入參數但無法改變 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.

瀏覽器相容性

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support No support 22.0 (22.0) No support No support No support
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support No support No support 22.0 (22.0) No support No support No support

Firefox 特定註記

  • 在 Firefox 24 前,strict mode 會隨著箭頭函數定義而生效,但之後已取消,明白宣告 strict mode 是需要的。
  • 箭頭函數和 Firefox3 加入、非標準的 Expression Closures (詳細資訊: Javascript 1.8) 有所不同,針對 Expression Closures 並無綁定 this 變數。
  • 在 Firefox 39 前, 單行終結符號 (\n) 錯誤地必允許在箭頭函數,現在這項錯誤已經修正以符合 ES6 標準,類似程式碼如 () \n => {} 將導致 SyntaxError 錯誤。

文件標籤與貢獻者

 此頁面的貢獻者: linjimmy168, foxbrush
 最近更新: linjimmy168,