読者です 読者をやめる 読者になる 読者になる

AirbnbのES6スタイルガイドを読んで

こんにちは丸山@h13i32maruです。

ES6の仕様がRC4になっており、正式リリースを今か今かと待ちわびている。とはいえもう個人で書くコードはES6一択。ES5には戻れない(それにしてもBabelの勢いがすごい)。

そんな感じでES6を書いてるわけだけど、つい先日にAirbnbがES6のスタイルガイドを公開したというのを見かけたので、ざっくり読んでみた。

Airbnb JavaScript Style Guide() {}

ほとんどの内容はすでにES5で一般的になっているものだったけど、一部ES6ならではのものがあった。賛成できるものもあったり、できないものもあったので、気になる項目だけ軽く紹介してみる。

constを使う

References

ES5まではvar fooというように変数を宣言してきたけど、このvarが曲者で他の言語とはちょっと異質な存在である。「ブロックスコープではなく、関数スコープ」「巻き上げにより必ず関数先頭で宣言されているという扱いになる」という点。詳細はググってもらうとして、ちょっと厄介。

そこでES6では新たに変数宣言の方法が2つ追加された。let fooconst foo。これらはvarとは違い、「ブロックスコープ」「巻き上げしない」という他の言語と同じような動きをする。加えてconstは定数扱いになる(再代入不可)。なので僕はES6で書くコードでは基本的にlet fooを使って変数を宣言している。

けど、このAirbnbのスタイルガイドでは基本的にconst fooを使うように書かれている。え?まじで?という感じで、ちょっとこれにはびっくりした。理由としては「一度変数に値を入れたら、再代入って基本しないでしょ?再代入するとコード読むの難しくなるし、イミュータブルにしよう」みたいな感じぽい。

まあ確かに普通にプログラムを書いていて変数に値を再代入するというのはあまり無いかもしれない(for文などのイテレーション除く)。とはいえすべての変数をconstで宣言するのはなにか違和感がある。何が違和感なのかというと「JavaScriptの定数には慣習的にFOO_BAR_BAZのように大文字スネークケースを使う」「constでは変数自体への再代入は防げるけど、プロパティの再代入は防げない」というあたり。

今後のES6界隈はこのAirbnbのスタイルガイドのようにconstが主流になるのか、それとも普通にletを使うのか、ちょっと気にかけておこうと思う。

for of使わない

Iterators and Generators

ES5で配列のイテレーションはforもしくはArray#forEachなどのイテレーションメソッドを使う事になる。for-inというのもあるけど、これは配列のイテレーションに使うことはない。

ES6では配列(だけじゃなくてIteratorを実装したもの全般)をイテレーションするためにfor-ofという構文が追加された。これで配列のイテレーションがすごく書きやすくなったので、個人的にES6では基本的にfor-ofを使っている。

それが、Airbnbのスタイルガイドではfor-ofは使わず、Array#map, Array#redueなどのメソッドを使うようにとなっている。先のconstを使うべしというのからもわかるようにすべての変数をイミュータブルにしよう、ループによる副作用をなくそうというのが理由みたい。Arrow Functionも導入されて確かに書きやすくなったけど、ここは好みが分かれそう。

single export

Modules, Naming Conventions

ES5には言語としてモジュール機能がなくてサードパーティのライブラリを使ったり、nodeならrequire関数を使ったりして実現してきた。

ES6ではimport/exportというモジュール機能が言語に組み込まれた。やったー!というわけで、ES6でプログラムを書く時は機能毎にモジュールに分割して適宜importして使っている。このimport/exportの使い方としてAirbnbのスタイルガイドにはwildcard importを使わないように書いてある。その理由が「読み込まれる側がdefault exportだけを持っていることが明確になるから」ということらしい。

一方で、ファイル名のガイドとして「単独のクラスをエクスポートしているファイルの名前は、クラス名と同じCamelCaseにする」ということも書いてある。

僕はこの2つのガイドにはすごく賛成。賛成というか、この2つを組み合わせてもうちょっと厳しくしたガイドを自分の中で決めている。

  • 全てのモジュール(ファイル)は単独のクラスだけをdefault exportし、ファイル名は必ずそのクラス名と同じにする
  • もし関数だけをモジュールとして切り出したい場合でもクラスを作り、そのスタティックメソッドとして実装する

偉そうに言っているが、OOPな言語では割りと当たり前のモジュール分割だとおもう。ただし、ディレクトリ名をどうするかはまだちょっと悩んでいる。CamelCase、snake_case、foobarbaz。




他の会社もES6のスタイルガイド公開して欲しい。