アロー関数式は、より短く記述できる、通常の function 式の代替構文です。また、this, arguments, super, new.target を束縛しません。アロー関数式は、メソッドでない関数に最適で、コンストラクタとして使うことはできません。

構文

基本的な構文

(param1, param2, …, paramN) => { statements } 
(param1, param2, …, paramN) => expression
// 上記の式は、次の式と同等です: => { return expression; }

// 引数が 1 つしかない場合、丸括弧 () の使用は任意です:
(singleParam) => { statements }
singleParam => { statements }

// 引数がない場合、丸括弧を書かねばいけません:
() => { statements }

高度な構文

// object リテラル式を返す場合は、本体を丸括弧 () で囲みます:
params => ({foo: bar})

// 残余引数デフォルト引数 をサポートしています
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { 
statements }

// 引数リスト内の分割代入もサポートしています
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f(); // 6

説明

hacks.mozilla.org の "ES6 In Depth: Arrow functions" も参照してください。

2 つの理由から、アロー関数が導入されました。1 つ目の理由は関数を短く書きたいということで、2 つ目の理由は this を束縛したくない、ということです。

関数の短縮形

var elements = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

elements.map(function(element) {
  return element.length;
}); // this statement returns the array: [8, 6, 7, 9]

// The regular function above can be written as the arrow function below
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

// When there is only one parameter, we can remove the surrounding parenthesies:
elements.map(element => {
  return element.length;
}); // [8, 6, 7, 9]

// When the only statement in an arrow function is `return`, we can remove `return` and remove
// the surrounding curly brackets
elements.map(element => element.length); // [8, 6, 7, 9]

// In this case, because we only need the length property, we can use destructuring parameter:
// Notice that the string `"length"` corresponds to the property we want to get whereas the
// obviously non-special `lengthFooBArX` is just the name of a variable which can be changed
// to any valid variable name you want
elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]

// This destructuring parameter assignment can be written as seen below. However, note that there
// is no specific `"length"` to select which property we want to get. Instead, the literal name
// itself of the variable `length` is used as the property we want to retrieve from the object.
elements.map(({ length }) => length); // [8, 6, 7, 9] 

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 that = this;
  that.age = 0;

  setInterval(function growUp() {
    // このコールバックは、期待されるオブジェクトの値を
    // `that` 変数で参照する。
    that.age++;
  }, 1000);
}

あるいは、適切な this の値を対象の関数(上の例では growUp() 関数)に渡すように、束縛関数を作成することもできました。

アロー関数自身は this を持ちません。レキシカルスコープの this 値を使います。つまり、アロー関数内の this 値は通常の変数検索ルールに従います(スコープに this 値がない場合、その一つ外側のスコープで this 値を探します)。

そのため、次のコードで setInterval に渡される関数の this の値は、外部関数の 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() メソッドは引数しか渡せません。thisArg は無視されます。

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));         // 2 を出力する
console.log(adder.addThruCall(1)); // やはり 2 を出力する

arguments を束縛しない

アロー関数は自身で arguments オブジェクトを持ちません。そのため、この例では、arguments は囲っているスコープでの同名変数への参照にすぎません。

var arguments = [1, 2, 3];
var arr = () => arguments[0];

arr(); // 1

function foo(n) {
  var f = () => arguments[0] + n; // foo は arguments を暗黙的に束縛している。arguments[0] は n である。
  return f();
}

foo(3); // 6

多くの場合、残余引数arguments オブジェクトの代わりに使えます。

function foo(n) {
  var f = (...args) => args[0] + n;
  return f(10);
}

foo(1); // 11

メソッドとして使われるアロー関数

前に述べたように、アロー関数式は非メソッド型の関数に最もよく合っています。これをメソッドとして使った時のことを見てみましょう:

'use strict';

var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log(this.i, this);
  }
};

obj.b(); // prints undefined, Window {...} (or the global object) 
obj.c(); // prints 10, Object {...}

アロー関数は自身の this を持ちません。Object.defineProperty() を使う例です。

'use strict';
var obj = {
  a: 10
};

Object.defineProperty(obj, 'b', {
  get: () => {
    console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...} (or the global object) 
    return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined' 
  }
});

new 演算子の使用

アロー関数はコンストラクタとして使用できず、new と共に使うとエラーになります。

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

prototype プロパティの使用

アロー関数には prototype プロパティはありません。

var Foo = () => {};
console.log(Foo.prototype); // undefined

yield キーワードの使用

yield キーワードはアロー関数内で使用できません(内部で入れ子になった関数が許可されている場合を除く)。結果として、アロー関数はジェネレーターとして使用できません。

関数の Body 部分

アロー関数は、「簡潔文体 (concise body)」か、もしくはより一般的な「ブロック文体 (block body) 」のどちらかを使用することができます。

簡潔文体 (concise body) においては、単一の式だけが記述できるので、その式が明示的に return される値となります。しかし、ブロック文体においては、自動的に return はされないので、明示的に return 文を使用する必要があります。

var func = x => x * x;                  // 簡潔構文の場合、明示せずとも"return" されます
var func = (x, y) => { return x + y; }; // ブロック文体では、明示的に "return" を宣言する必要があります

オブジェクトリテラルを返す

短縮構文 params => {object:literal} を使ってオブジェクトリテラルを返そうとしても、期待通りに動作しないことに注意しましょう。

var func = () => { foo: 1 };
// 呼び出した func() は undefined を返す!

var func = () => { foo: function() {} };
// SyntaxError: function 文には名前が必要

これは、括弧 ({}) 内のコードが文の列として構文解析されてしまっているからです(つまり、foo はオブジェクトリテラル内のキーでなく、ラベルとして扱われています)。

オブジェクトリテラルは括弧で囲むのを忘れないでください。

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

改行

アロー関数には括弧とアロー(矢印)の間に改行を入れられません。

var func = ()
           => 1;
// SyntaxError: expected expression, got '=>'

その上で、下記の例は、括弧を使って、更に引数の内側で改行を使うことで、綺麗で柔らかなコードに修正できることを確認しています。

var func = (
  a,
  b,
  c
) => (
  1
); 
// no SyntaxError thrown

解析の順序

アロー関数内のアロー(矢印)はオペレーターではないですが、アロー関数は通常の関数と異なり、オペレーターを引き継いだ特別な解析ルールを持ちます。

let callback;

callback = callback || function() {}; // ok

callback = callback || () => {};
// SyntaxError: invalid arrow-function arguments

callback = callback || (() => {});    // ok

さらなる例

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

(() => 'foobar')(); 
// "foobar" を返します
// (this is an Immediately Invoked Function Expression
// see 'IIFE' in glossary)

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]

// さらに簡潔な promise チェーン
promise.then(a => {
  // ...
}).then(b => {
  // ...
});

// 見た目に解析が簡単な引数なしのアロー関数
setTimeout( () => {
  console.log('I happen sooner');
  setTimeout( () => {
    // deeper code
    console.log('I happen later');
  }, 1);
}, 1);

仕様

仕様書 状態 コメント
ECMAScript 2015 (6th Edition, ECMA-262)
Arrow Function Definitions の定義
標準 初期定義
ECMAScript Latest Draft (ECMA-262)
Arrow Function Definitions の定義
ドラフト  

ブラウザーの実装状況

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeEdge MobileAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
Arrow functionsChrome 完全対応 45Edge 完全対応 ありFirefox 完全対応 22
補足
完全対応 22
補足
補足 The initial implementation of arrow functions in Firefox made them automatically strict. This has been changed as of Firefox 24. The use of 'use strict'; is now required.
補足 Prior to Firefox 39, a line terminator (\n) was incorrectly allowed after arrow function arguments. This has been fixed to conform to the ES2015 specification and code like () \n => {} will now throw a SyntaxError in this and later versions.
IE 未対応 なしOpera 完全対応 32Safari 完全対応 10WebView Android 完全対応 45Chrome Android 完全対応 45Edge Mobile 完全対応 ありFirefox Android 完全対応 22
補足
完全対応 22
補足
補足 The initial implementation of arrow functions in Firefox made them automatically strict. This has been changed as of Firefox 24. The use of 'use strict'; is now required.
補足 Prior to Firefox 39, a line terminator (\n) was incorrectly allowed after arrow function arguments. This has been fixed to conform to the ES2015 specification and code like () \n => {} will now throw a SyntaxError in this and later versions.
Opera Android 完全対応 32Safari iOS 完全対応 10Samsung Internet Android 完全対応 5.0nodejs 完全対応 あり
Trailing comma in parametersChrome 完全対応 58Edge ? Firefox 完全対応 52IE 未対応 なしOpera 完全対応 45Safari ? WebView Android 完全対応 58Chrome Android 完全対応 58Edge Mobile ? Firefox Android 完全対応 52Opera Android 完全対応 43Safari iOS ? Samsung Internet Android 完全対応 7.0nodejs 完全対応 あり

凡例

完全対応  
完全対応
未対応  
未対応
実装状況不明  
実装状況不明
実装ノートを参照してください。
実装ノートを参照してください。

関連項目

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

最終更新者: mdnwebdocs-bot,