アロー関数

これは Harmony(ECMAScript 6) 提案の一部であり、実験段階の技術です。
この技術の仕様は安定していません。ブラウザ互換性の一覧表を確認してください。またこれらの構文や動作は、仕様変更などにより、新しいバージョンのブラウザでは変更される可能性があるという点に注意してください。

アロー関数式(またはファットアロー関数)はfunction式に比べより短い構文を持ち、 this の値をレキシカルに束縛します。アロー関数は常に匿名関数です。

構文

// 基本構文:
(param1, param2, paramN) => { statements }
(param1, param2, paramN) => expression
   // これと同じ:  => { return expression; }

// 引数がひとつしかないときには丸かっこ()はオプションです:
singleParam => { statements }
singleParam => expression

// 引数がないときには丸かっこ()が必要です:
() => { statements }

// Advanced:
// object literal表現を返すときにはbody全体を丸かっこ()で囲む:
params => ({foo: bar})

// Rest parameters をサポートします。
(param1, param2, ...rest) => { statements }

詳しい構文の例はこちらで見ることができます。

param
引数の名前です。引数がないときはかっこ () で表します。引数をひとつしかとらない場合、かっこは必要ではありません。 (例: foo => 1)
statements or expression
複数のステートメントを含むときは、波かっこ {} で囲う必要があります。しかし、ひとつの式の場合は必要ではありません。また、式は暗黙的にその関数が返す値となります。

解説

こちらもご参考に "ES6 In Depth: Arrow functions" on hacks.mozilla.org.

アロー関数の導入には2つの要素から影響を受けました。より短い関数とレキシカルな this です。

より短い関数

いくつかの関数のパターンで、より短い関数を自由に使用できます。比較できる例を示します。

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 の値を定義していました。(コンストラクターでは新しいオブジェクト、 strict モードでの関数呼び出し時のundefined、関数が"オブジェクトのメソッド" として呼び出された場合のオブジェクトなどの場合など) これは、オブジェクト指向プログラミングをするうえでじれったいものだとわかりました。

function Person() {
  // Person() のコンストラクターは自分自身を `this` として定義します。
  this.age = 0;

  setInterval(function growUp() {
    // 非strict モードでは、growUp() 関数は `this` を Person() コンストラクターで定義された `this` とは違い、グローバル オブジェクトとして定義します。
    this.age++;
  }, 1000);
}

var p = new Person();

ECMAScript 3/5 では、この問題は this の値を外側で閉じた変数に代入することで修正できました。 

function Person() {
  var self = this; // `self` の代わりに `that` を選ぶこともあります。どちらかを選んで徹底するようにしましょう。
  self.age = 0;

  setInterval(function growUp() {
    // コールバックは期待したオブジェクトの値を変数 `self` で参照します。
    self.age++;
  }, 1000);
}

また bound function はしかるべき this の値を growUp 関数に渡すことができます。

アロー関数はそのコンテキストの this の値を捕捉するため、以下のコードは期待通りに動きます。

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| は 適切にperson オブジェクトを参照します。
  }, 1000);
}

var p = new Person();

strict モードについての関連事項

与えられた this がレキシカルなとき、strict モード の規則では thisは単に無視されます。

var f = () => {'use strict'; return this};
f() === window; // またはグローバル オブジェクト

このほかは 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

Returning object literals

objectリテラルを返す時にこのような構文を使うとparams => {object:literal}期待通りに動作しないことを覚えてください:

var func = () => {  foo: 1  };               // Calling func() returns undefined!
var func = () => {  foo: function() {}  };   // SyntaxError: function statement requires a name

その理由は波括弧の中はとしてパーシングされるからです。(例えば、ここでfooはobjectリテラルではなくラベル扱いになる)

objectリテラルを返すためには括弧で囲むことを覚えてください。

var func = () => ({ foo: 1 });

// 空のアロー関数は undefined を返します。
let empty = () => {};

(() => "foobar")() // "foobar" を返します

var simple = a => a > 15 ? 15 : a; 
simple(16); // 15
simple(10); // 10

let max = (a, b) => a > b ? a : b;


// 簡単な配列フィルターリング、マッピング、、、

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 45.0 22.0 (22.0) 未サポート 未サポート 未サポート
Feature Android Android Webview Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support 未サポート 45.0 22.0 (22.0) 未サポート 未サポート 未サポート 45.0

Firefox-specific notes

  • Firefoxでアロー関数の初期実装は自動的にstrictだったが、Firefox 24からは、"use strict";が必要になりました。
  • Arrow functions are semantically different from the non-standard Expression Closures added in Firefox 3 (details: Javascript 1.8), for Expression Closures do not bind this lexically.
  • Prior to Firefox 39, a line terminator (\n) was incorrectly allowed after arrow function arguments. This has been fixed to conform to the ES6 specification and code like () \n => {} will now throw a SyntaxError in this and later versions.

See also

ドキュメントのタグと貢献者

Contributors to this page: tkdezapii, jungjoo, teoli, uu59, yuxxxx
最終更新者: tkdezapii,
サイドバーを隠す