どうも!chuckです。
JavaScriptでは文末のセミコロンを省略できます。それはなぜかと言うと、勝手にセミコロンを自動挿入して補ってくれるためです。
ただ、最近コーディングしていて気づいたんですが、時々セミコロンを挿入してくれないんですよね。シンタックスエラーになってしまう。
なので、自動挿入には何か条件があるのか。あるとしたらどのようなものなのか。調べてみました。
まずは再現してみる
セミコロンが挿入されず、シンタックスエラーになるケースを再現してみます。
挿入されるパターン
こちらがシンタックスエラーにならない方。
こんなのも大丈夫。
挿入されないパターン
こちらはエラーになってしまいます。
エラーメッセージはTypeErrorですが、これはセミコロンが挿入されずシンタックスエラーになった結果、TypeErrorと見なされてしまっているのだと思います。
var x = 50の後にセミコロンを加えると、エラーは解消されます。
さっそくググる
こんなブログが。
セミコロンの挿入に関して、3つのルールがあるようです。
まずは1つ目。
1, コード中に文法的なエラーを含む場合、以下の条件を1つ以上満たすとエラー箇所の直前にセミコロンが挿入される。
1.1, エラー箇所の前に1つ以上の改行がある。
1.2, エラー箇所が } である。
例を出すとこんな感じですかね。
「 1 2 」は数値リテラルが並列しており、明らかなエラーです。
ただし、改行を挟むことにより、改行の前にセミコロンが挿入されて事なきを得ます。
console.log('hello') という処理文の後にセミコロンがなく、いきなり閉じカッコが来ています。これは本来エラーになりそうですが、セミコロンが自動挿入されたのか、エラーにはなりません。
うーん、あんまり自信ない。。。
次に2つ目のルールについて。
2. プログラムの末尾まで到達したときにエラーが発生した場合、セミコロンが導入される。
まあ、要は文末にセミコロンが無いとセミコロンを挿入してくれると。
ん?これって、1.1と一緒じゃない?
他の方のブログなどを読んでも、あまりその点については触れられていない…。なぜ??
1と2のルールに共通することは、エラー対策としてのセミコロン挿入ですね。
エラーが起こりそうになった場合、文末か、改行の前か、閉じ中カッコの前ならばセミコロンを挿入して防いでくれるといった感じでしょうか。
なので、以下のケースではセミコロンは挿入されません。
cの後にセミコロンが挿入されるかとおもいきや、されません。
これはこのように解釈されてしまっているからなんですね。
なので、c は関数ではないよと怒られてしまいます。
この場合はセミコロンの挿入以前の問題として、関数として間違っているとみなされてしまっているんですね。
そして、3つ目のルールについて。
restricted productionの後の”no LineTerminator here”の位置に改行が会った場合、そこにセミコロンが挿入されます。
まず、jsにはrestricted productionというものがあるようです。
これは 後置インクリメント、後置デクリメント、continue, break, return, throwの6つのことです。
(仕様よりスクショ。)
スクショの[no LineTerminator here]という部分で改行をすると、セミコロンが挿入されるとのこと。
以上の3つが、JavaScriptでセミコロンが自動挿入されるルールのようです。
まとめ
普段意識することはありませんが、調べてみると面白いですね。
ただ、1.1と2の違いが分からず、モヤモヤも残ります…。今後の仕様で変わっていくことはあるのでしょうか??
ただ、一つ言えることは、セミコロンはきちんと書いた方がいいということですね。
JavaScriptGoodPartsにもそのように推奨してますし、書くほうが無難です。
参考URL
分かりやすかったブログ記事
英語の勉強にもなるかもしれない記事
James Allardice - Understanding automatic semi-colon insertion in JavaScript
Ecmaの本家仕様
http://www.ecmascript.org/docs/tc39-2009-043.pdf
仕様から、セミコロン自動挿入に関して抜粋。