Javascriptでセミコロンを必ず付けるべき3つの理由

 一部で、javascriptにセミコロンを付けずに運用するコーディングルールが流行っているそうです。

 これは驚愕です。フロントエンドJavaScriptでは、セミコロンを付けることが常識であり共通認識だと考えてきました。

 たとえば、セミコロン省略スタイルでは以下のようにするようです。

console.log("a")
console.log("b")
console.log("c")

 最大の問題である、即時関数や配列リテラルについては、先頭にセミコロンをつけるようです。

console.log("a")
;(function(){
  console.log("b")
  console.log("c")
})()

;["d", "e"].forEach(function(o){
  console.log(o)
})

javascriptにセミコロンは不要か?

 コーディングルールに関することはしばしば不毛な議論を招きやすいのですが・・・。

 確かに、最近のモダンな言語にありがちなセミコロンの除去は、流行を捉えていて自然なように見えます。しかし、javascriptはセミコロンを付けて実装されることが前提となっていることから、バグを招く危険があります。

 Google JavaScript Style Guide(リンクは和訳版)でも、以下のように述べられています。

常にセミコロンを使います.
コードのセミコロンを省き, セミコロンの挿入を処理系に任せた場合, 非常にデバッグが困難な問題が起こります. 決してセミコロンを省くべきではありません.

 冒頭で挙げた例のとおり、即時関数などのカッコが続く構文は、セミコロンの自動補完が行われず、続いた文として解釈されてしまい、多くの場合はエラーになります。これは一般的な感覚からすると、あまり直感的でない動作です。

 そして、この「直感的でない」というのはとても良くないことです。ソースコードは人間が読むものですから、読んだままに動かなくてはなりません。

 セミコロンの排除は、構文の分離を非常にわかりづらいものにしてしまいます。

javascriptにセミコロンを使うべき3つの理由

1. 一部の特殊なルールより全体に統一したルールの方が遵守が容易である

 コーディング規約を策定することを考えてみましょう。

 セミコロンを省略するコーディングルールを運用するにあたって「余計な一文が増える」ということは、明確な欠点として挙げられます。

 試しに、コーディング規約の草案を考えてみましょう。

x. いかなる場合も行末のセミコロンを省略してはならない

 従来のセミコロンを付与するコーディング規約では上記のようになりますが、省略するルールを採用した場合…

x. 例外なく、行末のセミコロンを省略する
y. 即時関数や配列リテラル、演算式などの行頭には必ずセミコロンを付ける

 どちらがシンプルか、一目瞭然です。

 こういった、コードの記述に関する問題は、各人の好みであり、プロジェクト毎に異なることでもあります。

 しかし、いざ規約を策定する段階になったとき、より説得力のあるルールはどちらでしょうか?

 スキルレベルの違うメンバが多数存在するチームで、規約を遵守するためにはどちらが優れているでしょうか?

2. セミコロン省略により、コードレビューの手間が増える

 これは、行末にいちいちセミコロンを付与すること以上の労力を招きます。人間は間違いを犯す生き物ですから、どんなベテランのプログラマでもセミコロンの付け忘れなど毎回のように起こることでしょう。

 この問題に対する解決策として、JsHintなどの便利なコード品質チェックツールがあります。

 コード品質チェックツールは、こういった品質を下げるようなコードの発見を手助けするためのものですから、コードレビューで使わない手はありません。

 しかし、セミコロン省略を推進している、Semicolons in JavaScript are Optionalによれば、

My advice on JSLint: don’t use it. Why would you use it? If you believed that it helps you have less bugs in your code, here’s a newsflash; only people can detect and solve software bugs, not tools. So instead of tools, get more people to look at your code.

 そんなものは使うな、バグを発見するのはツールではなく人間だ。

 と述べられています。しかし、バグの発見やコードレビューを手助けするのがツールです。でなければ、JsLintやJsHintなどのコード品質チェックツールは普及しなかったでしょう。

 繰り返しになりますが、人間は間違いを犯します。そして、間違いを犯さないためには、可能な限りシンプルなルールに従うことです。そして、それを補助するツールを利用することを躊躇う必要はありません。

 こういった便利なツールが使えないコーディング規約が優れているとは思えません。セミコロンひとつ付けないことで節約できる労力は、こういったメリットを放棄してまで得るものなのでしょうか?

3. ツールによってはminifyができないことがある

 セミコロン省略によってminifyができないケースがあります。これも先のページで「minifyツールが悪い。google closure compilerはminifyできるじゃないか」と述べられていますが、minifyツールが多数ある理由を考えてみましょう。

 google closure compilerは悪い選択ではありません。しかし、プロジェクトによっては、それが適さないケースも中にはあるはずです。

 世の中のすべてのminifyツールが、行末セミコロンを確実に100%自動補完するように設計されているわけではないはずです。改行と空白を単に取り除くだけのスクリプトを即席で組むことだって考えられます。そういったときに余計なことは考えたくないものです。

まとめ

 一部のJavaScriptウィザードたちは、セミコロンの冗長さに気づき、それを無くそうと試みているのかもしれません。しかし、その他のJavaScriptプログラマは、その真意を知ることなく流されるべきではありません。

 それが本当に優れていると断言できますか?「著名な人が言っていたから」ではなく、あくまで自分で考えて実行すべきです。

 しかし、それがどんな内容であろうと、当人とそのメンバーが納得できるのであれば問題はありません。それは当人たちの問題であって、そのコミュニティで閉じられるべき内容です。

 こういった話題は、不毛でつまらないものになりがちですが、そんな柔軟性がJavaScriptの魅力でもあります。

 今後、ES6が主流になれば、また違った結論となるかもしれません。時代の変遷に応じて、柔軟に対応していきたいものですね。