今さらだけどJavaScriptのアロー関数の使い方を調べました

f:id:tsubasa123:20170621170607j:plain

こんにちは、つばさ(@tsubasa123)です。

ES2015の話題が出るようになってそろそろ2年くらい経つでしょうか。随分と長い間勉強をサボっていたもです。今後のカスタマイズをより有意義なものにするためにも今年はしっかりと勉強を進めていきたいところです。

今年はカスタマイズだけでなく、JavaScriptの勉強過程とかも書いていこうかなと考えております。勉強においてもアウトプットって大事なので。つまらないと思う方の方が多いのは承知ですが、よければお付き合いください。

まずは個人的な目玉機能、アロー関数から調べてみました。これは早く使えるようになってもらいたいものです。

とにかく短く書ける

なんといってもこれですね。今まではfunctionという記述が必要でしたがこれからは

const f = (x, y) => {
return x + y;
};
f(1, 2); // 3

このように() => {}と記述できるようになりました。圧倒的省略ですね。さらに、引数が1つならカッコも省略できます。

const f = x => {
return x * x;
};
f(3); // 9

さらにさらに、文が1行ならブレースとリターンも省略できます。

const f = x => x * x;
f(3); // 9

さすがにやりすぎな気がしますが、ここまで短く書くことができます。

慣れれば書き手としては最高に気持ち良さそうですね。反対に人のソースを読むときは少し混乱しそう。慣れれば大丈夫なのかな。

thisを束縛できる!

これ!これを待ってた。JavaScriptの初学者を惑わすthisのスコープ。アロー関数を利用することでthisが束縛されるようになりました。アロー関数内のthisの値は実行時ではなく、定義時にされます。

const P = function(name) {
this.name = name;
this.init();
};
P.prototype.init = function() {
setTimeout(() => {
console.log(this.name);
}, 0);
};
new P('tsubasa'); // tsubasa

これこれ。thisのコンテキストがnewによって作成された新しいオブジェクトになっています。なのでthis.nameで初期化時に定義した値にアクセスできるようになります。今までは、

const P = function(name) {
this.name = name;
this.init();
};
P.prototype.init = function() {
var self = this;
setTimeout(function() {
console.log(self.name);
}, 0);
};
new P('tsubasa'); // tsubasa

このようにthisの参照を変数格納したりしていましたよね。こんなコード腐るほど書いてきましたがこれから解放されるときが来たようです。こんな便利ならもっとまじめに勉強しておけばよかったと反省しました。

また、thisのスコープが関数定義時に決定することにより、イベントハンドラでは今までは対象となるDOM要素がthisにバインドされなくなります。

jQueryのイベントハンドラやイテレーション処理にアロー関数を利用すると最初は少し戸惑うかもしれません。が、イベントハンドラであればイベントオブジェクトから、イテレーションであれば仮引数からそれぞれ対象の要素がとれるので困ることはないと思います。

関数定義時に仮引数を初期化できる

これもなかなか有能な機能です。他の言語(と言ってもそんなに詳しくないですが)では大体できていたのになんでできないんだろうと思っていたやつでした。これもES6から利用可能に。

const f = (x = 1, y = 2) => {
console.log(x + y);
}
f(); // 3

argumentsが使えない

これはちょっと残念なポイント。でもまぁ、thisの束縛の恩恵に比べればかわいいものです。と思っていたら、かわりに残余引数という機能が加わっており、今までと同じようにすべての引数を持つ配列が利用可能となっていました。正確には、従来のargumentsは配列ではなく配列のようなオブジェクトだったため、Arrayオブジェクトが提供するメソッドを利用することはできませんでしたが、今回の可変長引数は配列なのでひと手間加えなくても継承されたメソッドが利用可能となっています。やったね。

const f = (...args) => {
console.log(args);
};
f(1, 2, 3); // [1, 2, 3]

変数名は自由に決められる分、今まで以上に便利に使えそうです。

明示した仮引数と組み合わせて使うことも可能で、残りの引数が全て配列として格納されることになります。

const f = (x, ...args) => {
console.log(args);
};
f(1, 2, 3); // [2, 3]

また、関数が持つlengthプロパティにカウントされないという特徴もあるようです。ちなみにlengthプロパティは関数に定義された仮引数の数を取得することができるプロパティです。ちなみに私は使ったことがありません。

コンストラクタとしては使えない

class構文が使えるようになるのでこれからはあまりコンストラクタ関数を使う機会がなくなるかもですが、念のため覚えておきます。

const P = (name) => {
this.name = name;
};
P.prototype.hello = function() {
console.log(this.name);
};
const p = new P('tsubasa');
p.hello(); // Uncaught TypeError: Cannot set property 'hello' of undefined

このようにエラーになりますので気をつけましょう。

さいごに

JavaScriptを真面目に勉強したのはいつぶりでしょうか。やはりおもしろい言語です。

ではでは、最後までお付き合いいただきありがとうございました。