JavaScriptには、関数式を簡略化したアロー関数という関数の記法があります。
書き方がさらにシンプルになる他、通常の関数とは少し違った側面も持ちます。

今回は、アロー関数の構文をおさらいし、従来の関数との違いについて解説していきます。

アロー関数

アロー関数は、ES6から新しく導入された関数記法で、名前の通り=>を使って関数を定義します。
関数式を簡略化するために考案されたため、関数式に書き方が似ています。

アロー関数の基本構文は以下です。

// アロー関数の宣言構文
(引数1, 引数2, ...) => {
  実行する処理;
};

// アロー関数を変数に代入する形
let 変数名 = (引数1, 引数2, ...) => {
  実行する処理
};

変数名();

関数式のfunctionキーワードが無くなり、代わりに=>が使われているのが分かります。
関数式の書き方に慣れていれば、よりシンプルで扱いやすいでしょう。

では、実際にアロー関数を書いてみます。

let averageHeight = (a, b, c) => {
  let totalHeight = a + b + c;
  return totalHeight / 3;
};

console.log(averageHeight(160, 165, 170)); // 165

3人の身長の平均を求めています。戻り値や引数の使い方は、通常の関数で扱う時と変わりありません。

アロー関数と従来の関数の違い

アロー関数は、既存の関数定義を簡略化するために導入されたため、書き方が短くなっただけと思われがちですが、通常の関数と別の挙動を起こすという特徴があります。

thisを固定化する

アロー関数の一番の特徴は、通常の関数とthisの扱いが異なる点です。

そもそもthisとは、読み取り専用のグローバル変数のようなものであり、どこからでも参照が可能です。
通常の関数では、呼び出し元のオブジェクトを参照しますが、スコープや状況によってthisの値が変化します。

しかし、アロー関数では、アロー関数が定義された段階でthisが固定化されます。
つまり、アロー関数のthisが定義時に設定された対象のまま変化することがないということです。

言葉だけだとイメージしにくいため、サンプルコードを見てみましょう。

まず、関数式の場合です。

window.color = 'red'; // グローバル変数としてcolorを定義

let sampleFunc = function() {
  console.log(this.color);
};

sampleFunc(); // 関数呼び出し
// 'red'

let obj1 = {
  color: 'yellow',
  func: sampleFunc
};

let obj2 = {
  color: 'blue',
  func: sampleFunc
};

obj1.func(); // メソッド呼び出し
// 'yellow'
obj2.func(); // メソッド呼び出し
// 'blue'

関数式のthisは、宣言元のオブジェクトが参照されるため、thisの値が変化していることが確認できます。

次にアロー関数の場合です。

window.color = 'red'; // グローバル変数としてcolorを定義

let arrowFunc = () => {
  console.log(this.color);
};

arrowFunc(); // 関数呼び出し
// 'red'

let obj1 = {
  color: 'yellow',
  func: arrowFunc
};

let obj2 = {
  color: 'blue',
  func: arrowFunc
};

obj1.func(); // メソッド呼び出し
// 'red'
obj2.func(); // メソッド呼び出し
// 'red'

アロー関数では、関数が宣言された時点でthisが確定されます。そのため、thisを何度参照しても値は'red'です。

ES5以前は、thisを意味する内容が状況によって変更されてしまうのを抑えるために、bindメソッドが使用されていましたが、アロー関数の導入によってその必要がなくなりました。
反対にに、その都度thisの内容を変化させたい場合には、アロー関数の使用を控える方が良いでしょう。

コンストラクタを持たない

コンストラクタとは、関数を使って定義されたオブジェクトです。
通常は、newを使ってオブジェクトを生成することができます。雛形としてオブジェクトを定義し、その都度生成することが可能です。

関数式では以下のよう書くことができます。

let Info = function(id, name) {
  this.id = id; //引数を格納
  this.name = name;
};

let getInfo = new Info(1, 'Sam'); // コンストラクタの生成

console.log(getInfo.id, getInfo.name); // 1, 'Sam'

しかし、アロー関数ではコンストラクタを生成することができません。

let Info = (id, name) => {
  this.id = id;
  this.name = name;
};

let getInfo = new Info(1, 'Sam');

console.log(getInfo.id, getInfo.name);
// 'Uncaught TypeError: Info is not a constructor'

argumentsを持たない

argumentsは、関数内のみで利用できるオブジェクトです。
通常は、配列のようにaruguments[i]という形で関数に渡された値をすべて取得することができます。

関数式では以下のような結果になります。

let sampleFunc = function(a, b, c) {
  for (let i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}

sampleFunc(1, 2, 3, 4, 5); // 1, 2, 3, 4, 5

しかし、アロー関数の場合は、argumentsを持たないため、エラーになります。

let sampleFunc = (a, b, c) =>
  for (let i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}

sampleFunc(1, 2, 3, 4, 5);
// 'Uncaught ReferenceError: arguments is not defined'

まとめ

今回は、アロー関数と従来の関数の違いについて解説しました。
はじめはメリットを感じにくいかもしれませんが、アロー関数ではある固まった処理を行いたい時に役立ちます。

まずは以下のポイントをおさえながら、アロー関数について理解を深めていきましょう。

// ポイント
* アロー関数は、関数式を簡略化した関数記法
* thisを固定化する
* コンストラクタを持たない
* argumentsを持たない

アロー関数の関連記事

アロー関数
argumentsオブジェクト
thisの振る舞い