可読性アップのためのes2015入門


さてjavascriptを書いている皆さん、 **es2015**への対応準備はいかがでしょうか？
個人的には **2016年こそがes2015元年になるのではないか(ややこしい)**という見立てでおります。

無論、ブラウザ自体の対応はまだまだなのですが、
ブラウザ互換のjavascriptに変換してくれる[Babel](https://babeljs.io/)も(あるていど)安定し、
[browserify](http://browserify.org/)等々との連携も便利になってきたこの頃、意識しなくても使えるようになってきたのでは、というこのごろです。

*「そうは言っても、本来ブラウザで動かないし、javascriptに新しい機能が付くわけでもないし、使うメリットなんてそんなにないのでは？」*
と思う方もいるかもしれません。自分もしばらくそう思ってました。

しかし明確なメリットが一つあります。
**javascriptならではの読みづらい部分を、圧倒的に読みやすく書き直せる**ことです。

そんなわけでこの記事では、javascriptの嫌なところを読みやすく書きなおすという観点のみで、es2015を紹介してみます。

## class

こちらに何の変哲もないjavascriptがあります。押したらalertが出るだけのボタンを作るやつですね。

```javascript
var HelloButton = function (name, btn) {
   this.name = name;
   this.btn = btn;

   this.setListener();
};

HelloButton.prototype.hello = function () {
    alert("hello, my name is " + this.name + " !");
};

HelloButton.prototype.setListener = function () {
    var that = this;
    this.btn.addEventListener('click', function (e) {
        that.hello();
    });
};

```

javascriptを書いている人なら、普通に「あ、クラスだ」と思うかもしれません。

しかしこれ厳密に言えば、これは「クラスっぽいもの」であってクラスではありませんし、別の書き方で「クラスっぽいもの」を実現している人もいます。（privateなプロパティはvar宣言にするなど）

また、これが「クラスっぽいな」と思うのは、prototypeの拡張が後からごろごろ書いてあるからであって、
例えば最初の５行くらいを見ただけでは、この`HelloButton`という関数を、関数として使うのかクラスとして使うのかは判断しきれません。

それがes2015を使えばこのとおり、どう見たってクラスだね！というようなコードで書けます。

```javascript
class HelloButton {
    constructor (name, btn) {
        this.name = name;
        this.btn = btn;

        this.setListener();
    }

    hello () {
        alert("hello, my name is " + this.name + " !");
    }

    setListener () {
        var that = this;
        this.btn.addEventListener('click', function (e) {
            that.hello();
        });
    }
}
```

coffeescript等を書いている人にとっては、とっつきやすい記法ではないでしょうか。extends等も同じような感じでできます。

ちなみにこちら、新しいリテラル（書き方）が提供されたというだけで、内部実装は前者と後者ほぼ変わらないということに注意です。
新しくクラスの概念ができたというよりは、みんながよく使う実装に正式な書き方ができた、という流れなのです。

## arrow function

さて上記の例の中には他にも、javascriptを書く時に気持ち悪いと思うポイントが含まれています。例えばこちら、`setListener`の中身を取り出したものです。

```javascript
var that = this;
this.btn.addEventListener('click', function (e) {
    that.hello();
});
```

その`that`はなんなんだと。

念のため解説しておくと、こちらを`that`なしで、そのまま`this.hello()`と書くとエラーになります。
`var that = this`の行の時点では、`this`には自分自身・つまり`HelloButton`のインスタンスが入っていますが、
`addEventListener`に渡されたfunctionの中・`that.hello()`の部分では、thisにはボタンの要素が入っています。
当然ボタンの要素はhelloメソッドを持っていないので、`this.hello()`で呼び出すとエラーになります。それを避けるため、`HelloButton`のインスタンスがとれるタイミングで一度変数に代入しておき、後から参照する、という書き方がよく用いられているわけです。

この厄介な都合を避ける書き方も、es2015では提供されています。「arrow function」というやつです。


```javascript
this.btn.addEventListener('click', (e) => {
    this.hello();
});
```

`function (e) { ... }`ではなく、`(e) => { ... }`という書き方にすることで、関数内部の`this`は、その外側の`this`を引き継ぐようになります。これで分かりやすいですね。
クラスを使った実装をする場面では少なくとも、このように`this`の内容がころころ変わらないように意識したほうが、読みやすいコードになると思います。

## template

また、この辺も書く時にイライラする部分です。

```javascript
alert("hello, my name is " + this.name + " !");
```

変数が入り混じった文字列を作りたい時の書き方ですね。これくらいなら変数が一つなのでなんとかなりますが、３つや４つと増えてきた時には見づらくてかなわないですね。

そこでes2015の「template」記法が使えます。

```javascript
alert(`hello, my name is ${this.name} !`);
```

1, クオートを｀に置き換える
2, 変数を入れ込みたい部分を`${ ... }`で囲む

とすることで、文字列全体を一組の｀｀でまとめつつ、展開が必要なところだけ整理して書くことができます。ちなみに改行もOKです。

## つまり

すべてを反映すると、最初のコードはこんな感じになります。

```javascript
class HelloButton {
    constructor (name, btn) {
        this.name = name;
        this.btn = btn;

        this.setListener();
    }

    hello () {
        alert(`hello, my name is ${this.name} !`);
    }

    setListener () {
        this.btn.addEventListener('click', (e) => {
            this.hello();
        });
    }
}
```

色んな面で見やすくなったのではないでしょうか。
これなら、例えばRubyしか書いたことがない人でも、なんとなく読み取ってくれそうな気配さえします。

また結果的に、`function`文を使う場面がなくなっていることにも注目です。


## 環境構築

さて、みなさんes2015が書きたくなってきましたよね。
現状そのために必要な環境構築は、以下の様な感じです。

### nodeをご利用のみなさま
**→今すぐ書き換えちゃいましょう。**

- 一部`use strict`が必須です。
- es2015をサポートし始めたのが4.0.0あたりからなので、package.jsonでenginesを4.0.0以上にするのをおすすめしてます。

### フロントエンジニアのみなさま

**→babel環境をととのえましょう。**

- [Babel · The compiler for writing next generation JavaScript](https://babeljs.io/)

- 色んな開発環境で使えるようになってますが、import/exportまで含めてちゃんと使えるという意味では、webpack+babelかbrowserify+babelifyがおすすめです。
- 個人的には[こんなかんじ](https://github.com/fnobi/hinagata-gulp/blob/hinagata_browserify_babel/src/gulpfile.coffee#L64)で使ってます。

ではではみなさま、今年も読みやすいjavascriptを書いていきましょうー！