JavaScriptのセミコロンは必ず付けるべきなのか?

【結論】
JavaScriptでは、文の最後にセミコロンを付ける必要がある

・但し、特定の条件を満たしていれば、
 JavaScript側が自動でセミコロンを付与してくれる。

・例外条件を全て把握してコードを記述するのは難しいので、
 初めのうちは、セミコロンを全て付けた方がベター

・兎にも角にも、現場のスタイルガイドのに従うべき

【目次】


【本題】

疑問→セミコロン(;)を付けなくても機能するのはなぜか?

JavaScriptでは、文を見分けるため、
行の最後にセミコロンを付ける必要があります。

但し、実際に使ってみると、
セミコロン(;)を付けずとも正常に動作する場面が多々あります。

なぜ、セミコロン(;)を付けなくても機能するのか?
セミコロンを(;)付ける必要はあるのか?
気になったので、調べてみました。

自動セミコロン挿入(ASI)

セミコロン無しで動作するのは、
自動セミコロン挿入(Automatic Semicolon Insertion)
という機能がJavaScriptに存在するからです。

これは特定の条件を満たしている場合、
JavaScriptが自動的にセミコロンを付与してくれる機能です。

その条件が、かなり細かくややこしいのですが、
簡潔に説明すると下記の通りです。

1:次の条件で、プログラムが文法的に許可されないトークンが含む場合
・当該トークンの前に改行がある
・当該トークンが閉じ中括弧{}である

トークン:文法上の最小の構成要素、1 2 3 "abc"といった数値や
文字列リテラル、if,while,for,functionといったキーワード、

  1. ,-,=などの記号はすべてトーク

2:ファイル末尾に到達したときに、セミコロンを挿入しなければ
 プログラムを解釈できない場合

#ASI適用前
{ 1
2 } 3

#ASI適用後
{ 1
;2 ;} 3;

上記の通り、2の改行の前と、}の前と、
ファイルの末尾である3の後ろにセミコロンが挿入されます。


3:「return, throw, break, continue, ++, —」が出現した時

#ASI適用前
return
a + b;
#ASI適用後
return;
a + b;

上記の通り、returnの後ろにセミコロンが挿入されます。

ASIによる弊害

return {
  a: 1,
  b: 2,
  c: 3
};
return
{
  a: 1,
  b: 2,
  c: 3
};

上の記述だと、正しくオブジェクトが返るのですが、
下だと、returnがセミコロンで区切られてしまい、
返り値はundefinedとなります

a = b + c

(function() {
    var x, y, z;
})()

このケースは、ASIによってセミコロンがcの後に挿入されるように
思えるのですが、そうはならないそうです。




もうね・・・




よく分からん!!



この時点で、面倒くさいから、全部セミコロンつければ
いいじゃ無いかと思いましたが、
一応業界全体の傾向を調べる事にしました、。


セミコロン推奨派のスタイルガイド

色々のスタイルガイドを見て行くと、
セミコロン推奨が多い傾向にありました。


Google JavaScript Style Guide
Googleによるスタイルガイドです。

JavaScriptの言語仕様に関するルール - Google JavaScript スタイルガイド - 日本語訳 - atwiki(アットウィキ)

常にセミコロンを使います。
暗黙的なセミコロンの挿入に依存することは、
微妙な、デバッグしにくい問題を引き起こします。もっと良い方法を選びましょう。


jQuery JavaScript Style Guide
jQueryによるスタイルガイド

JavaScript Style Guide | Contribute to jQuery

Semicolons
Use them. Never rely on ASI.


Airbnb JavaScript Style Guide
Airbnbのスタイルガイドです。

Airbnb JavaScript スタイルガイド() { | javascript-style-guide

なぜ? JavaScriptセミコロンなしで改行を検出すると、
自動セミコロン挿入(Automatic Semicolon Insertion)と呼ばれる一連の規則を使用して、
その改行をステートメントの終わりと見なし、(名前が示すとおり)改行の前にセミコロンを
入れなければその行が壊れると考えた場所に、セミコロンを配置するかどうかを決定します。
ただし、ASIにはいくつかの風変わりな動作が含まれており、
JavaScriptが改行を誤って解釈した場合、コードは壊れます。
新機能がJavaScriptの一部になるにつれて、これらのルールはより複雑になります。
ステートメントを明示的に終了し、不足しているセミコロンを検知するようにリンターを構成すると、
問題に遭遇するのを防ぐのに役立ちます。


Node.js Style Guide
Node.jsのスタイルガイドです。

Felix's Node.js Style Guide(和訳)

あなたからセミコロンを奪おうとする反抗的な軍隊があるようです。
でも確かに私達の伝統的な文化はまだ元気に生き残っています。
だからコミュニティに従って、セミコロンを使いなさい!

セミコロン非推奨派のスタイルガイド

一方で、セミコロン反対のスタイルガイドも存在します。


JavaScript Standard Style

https://standardjs.com/rules.html#semicolons:titlee

No semicolons – It's fine. Really!


セミコロン反対派の主な主張は下記の通りです。

JavaScriptがそもそも多様な書き方を許す言語である(セミコロン云々を抜きにしても)。
・ASIに頼れば、ステートメント末尾は \n のみで十分である(セミコロンを付加するのは冗長)。
・改行後の(function() {...})() と結合して関数呼び出しと認識される件については、
 変わりに !function() { ... }() と記述すれば回避可能。



うん!初心者には関係無いな!!(達観)


総括

初心者が覚えておくことは、ステートメント末尾にはセミコロンを付けること
( そしてreturnで値を返すときは決して直後に改行を入れないこと! )」
それだけ!!

もちろん現場によって、セミコロン推奨の場合もあるので、
その際は、しっかり仕組みを理解して利用しましょう。