uhyohyo.net

JavaScript初級者から中級者になろう

十六章第十回 アロー関数

このページの最終更新日:

今回も短いです。今回紹介するのはアロー関数式です。これは関数を作る新しい文法です。

関数を作る式は次のような形でしたね。


function (x, y, z){ ... }

ES2015で追加されたアロー関数式を使うと、これは次のように書けます。

(x, y, z)=>{ ... }

短いですね。functionというキーワードがなくなり、引数部分と本体部分を=>でつなげた形です。アロー関数という名前はこの部分が矢印に見えることに由来しています。

アロー関数の特徴

このようにして作られたアロー関数には2つの特徴があります。ひとつはコンストラクタとして使用できないということです。最近こういうのをよく見ますね。そもそも関数が普通の関数としてコンストラクタとしても使えるという状況にあまり需要がないのでわけられるときは分けようという魂胆なのでしょう。

もうひとつはthisを引き継ぐということです。つまり、関数の中でのthisはこの関数が作られたとき(すなわち関数の外)のthisと同じになります。これはコールバック関数を作るときにthisをそのままにしたいときに便利です。クロージャの回で出てきた次のサンプルを思い出してください。


function MyDiv(name){
  this.div = document.createElement("div");
  this.name=name;
  this.div.appendChild(document.createTextNode("このdiv要素は"+name+"です"));
  document.body.appendChild(this.div);

  this.div.addEventListener('click',(function(e){
    console.log(this.name);
  }).bind(this),false);
}

var div1 = new MyDiv("div1");

アロー関数を用いるとこれは次のように書けます。bindが無くなり分かりやすくなりました。


function MyDiv(name){
  this.div = document.createElement("div");
  this.name=name;
  this.div.appendChild(document.createTextNode("このdiv要素は"+name+"です"));
  document.body.appendChild(this.div);

  this.div.addEventListener('click', (e)=>{
    console.log(this.name);
  }, false);
}

var div1 = new MyDiv("div1");

省略記法

アロー関数は、より簡潔に書けるようにするためにいくつかの省略記法があります。

引数の省略

まず、引数がひとつのときは引数リストの括弧を省略してx=>{ ... }とできます。

ただし、引数が1つであってもただの変数ではなく分解代入の形だったり、...argsのような形のときは括弧を省略できません。

なお、引数が0個のときは括弧を省略できません。()=>{ ... }とする必要があります。

本体部分の省略

関数の本体部分がreturn 式;という形のとき、何かの計算をしてその値を返すだけの関数の場合はこれを(...)=> と省略できます。具体例としては、次の2つの関数は同じです。


var func1 = (x, y)=>{ return x+y; };

var func2 = (x, y)=> x+y;

めちゃくちゃ簡潔になりました。特にfunc2は、引数xとyを受け取ってx+yを返す関数であるということが分かりやすくなっています。ただ、この書き方はどこまでが関数定義なのか分かりにくい場合もあり、使い過ぎには注意が必要です。そして、この省略をする場合{ }は必ず省略する必要があります。(x, y)=>{ x+y }とすると返り値がない関数になってしまいます。

以上の2つの省略を組み合わせるとこんな感じで使えます。


var arr = [1, 2, 3, 4, 5];

console.log(arr.map(x=> x*2)); // [2, 4, 6, 8, 10]

注意点として、オブジェクトリテラルで作ったオブジェクトを返す関数で上記の省略を使う場合、このように括弧で囲まないとうまくいきません。これは括弧がないと{ ... }がオブジェクトリテラルではなく関数本体を囲むやつとして認識されるからです。


var func = x=>({ x });

console.log(func(3)); // {x: 3}

なお、この記法ではfunction式のときのように関数に名前をつけられません。ただし、前々回で説明したように変数に代入する場合などはいい感じに自動的に名前が付けられます。