ES2015(ES6)備忘録〜アロー関数〜

goran

@goran_nasai

こんにちは。GORAN です。今回でES2015(ES6)備忘録は(ひとまず)ひと区切りです。

アロー関数

関数式の代替構文。functionキーワードやreturn文を省略して関数を記述できます。

従来の関数式
function (a) {
  return a + 100;
}
アロー関数
// "function" キーワードを省略できる
(a) => {
  return a + 100;
}

// "{}" と "return" を省略できる
(a) => a + 100;

// "()" を省略できる
a => a + 100;
仕様詳細
  • returnを省略できるのは、処理内容のステートメントが単一の場合だけです。

    • 厳密には、「ステートメントがひとつだけ(簡潔文体)のとき{}を省略できて、{}省略時はステートメントの結果が返り値になるため、returnが不要になる(暗黙的にreturnされる)」という構図です。
  • ()を省略できるのは、引数が単一の場合だけです。
返り値がオブジェクトリテラル式の場合

式の周りに()が必要になります。

オブジェクトリテラル式
params => ({foo: "a"});
return 文を省略しない

特に React で関数コンポーネントを記述する場合、「constreturn文を省略するか」という命題があります。僕個人としてはこれまで「何となく」省略してこなかったんですが、一番文句言われなさそうな React コンポーネントの書き方を読んで、その「何となく」というのは「処理を足したくなったときに書き換えが生じることへの嫌悪感」だったんだと気づきまして、現在はその思想のもと、returnを省略しない記法で統一しています。

他のES2015新機能と組み合わせた記述も可能です。

残余引数
(a, b, ...r) => expression
デフォルト引数
(a = 400, b = 20, c) => expression
デストラクチャリング
([a, b] = [10, 20]) => a + b;
({ a, b } = { a: 10, b: 20 }) => a + b;

thisへの結び付けを持たない

アロー関数の最大の特徴であり、多くの JavaScript プログラムでアロー関数が採用されている理由のひとつでしょう。「thisへの結び付けを持たない」というのはアロー関数が通常の関数と違って独自のスコープを持たず、アロー関数の外側と内側でスコープが保持されることを意味しています。言い換えれば、アロー関数はthisを保有せず、レキシカルスコープのthisを参照するということです。

このthisの扱い方について、通常の関数との違いをコールバックを記述した場合で見てみます。

以下のコードでは、thisobjオブジェクトであることを期待していますが、実際にはsetTimeoutwindowスコープで実行され、countプロパティはwindowスコープではないため、コンソールにはNaNが表示されます。

通常の関数
var obj = {
  count: 10,
  doSomethingLater: function () {
    setTimeout(function () {
      this.count++;
      console.log(this.count);
    }, 300);
  },
};

obj.doSomethingLater();

アロー関数でコールバックを記述すると、thisdoSomethingLater関数の呼び出しのコンテキストであるobjを指すため、期待した通りの実行結果が得られます。

アロー関数
var obj = {
  count: 10,
  doSomethingLater: function () {
    setTimeout(() => {
      this.count++;
      console.log(this.count);
    }, 300);
  },
};

obj.doSomethingLater();

おわりに

次回は「チーム作り」だったり「Biz との関わり方」みたいなちょっとポエミーなものを書こうと思っています。