コンパイラかく語りき

import { Fun } from 'programming'

JavaScriptのセミコロン自動挿入について調べた

どうも!chuckです。

JavaScriptでは文末のセミコロンを省略できます。それはなぜかと言うと、勝手にセミコロンを自動挿入して補ってくれるためです。

ただ、最近コーディングしていて気づいたんですが、時々セミコロンを挿入してくれないんですよね。シンタックスエラーになってしまう。

 

なので、自動挿入には何か条件があるのか。あるとしたらどのようなものなのか。調べてみました。

 

 

まずは再現してみる

セミコロンが挿入されず、シンタックスエラーになるケースを再現してみます。

 

挿入されるパターン

こちらがシンタックスエラーにならない方。

f:id:chuck0523:20150919090043p:plain

 

こんなのも大丈夫。

f:id:chuck0523:20150919090218p:plain

 

挿入されないパターン

こちらはエラーになってしまいます。

f:id:chuck0523:20150919090657p:plain

 

エラーメッセージはTypeErrorですが、これはセミコロンが挿入されずシンタックスエラーになった結果、TypeErrorと見なされてしまっているのだと思います。

f:id:chuck0523:20150919090705p:plain

 

var x = 50の後にセミコロンを加えると、エラーは解消されます。

f:id:chuck0523:20150919090716p:plain

 

さっそくググる

こんなブログが。

JavaScriptの行末セミコロンは省略すべきか

 

セミコロンの挿入に関して、3つのルールがあるようです。

まずは1つ目。

1, コード中に文法的なエラーを含む場合、以下の条件を1つ以上満たすとエラー箇所の直前にセミコロンが挿入される。

 1.1, エラー箇所の前に1つ以上の改行がある。

 1.2, エラー箇所が } である。

 

例を出すとこんな感じですかね。

f:id:chuck0523:20150919094907p:plain

「 1 2 」は数値リテラルが並列しており、明らかなエラーです。

ただし、改行を挟むことにより、改行の前にセミコロンが挿入されて事なきを得ます。

 

f:id:chuck0523:20150919095556p:plain

console.log('hello') という処理文の後にセミコロンがなく、いきなり閉じカッコが来ています。これは本来エラーになりそうですが、セミコロンが自動挿入されたのか、エラーにはなりません。

 

うーん、あんまり自信ない。。。

 

次に2つ目のルールについて。

2. プログラムの末尾まで到達したときにエラーが発生した場合、セミコロンが導入される。

まあ、要は文末にセミコロンが無いとセミコロンを挿入してくれると。

ん?これって、1.1と一緒じゃない?

他の方のブログなどを読んでも、あまりその点については触れられていない…。なぜ??

 

1と2のルールに共通することは、エラー対策としてのセミコロン挿入ですね。

エラーが起こりそうになった場合、文末か、改行の前か、閉じ中カッコの前ならばセミコロンを挿入して防いでくれるといった感じでしょうか。

 

なので、以下のケースではセミコロンは挿入されません。

f:id:chuck0523:20150919102119p:plain

cの後にセミコロンが挿入されるかとおもいきや、されません。

これはこのように解釈されてしまっているからなんですね。

f:id:chuck0523:20150919102242p:plain

 

なので、c は関数ではないよと怒られてしまいます。

この場合はセミコロンの挿入以前の問題として、関数として間違っているとみなされてしまっているんですね。

 

 

そして、3つ目のルールについて。

restricted productionの後の”no LineTerminator here”の位置に改行が会った場合、そこにセミコロンが挿入されます。

まず、jsにはrestricted productionというものがあるようです。

これは 後置インクリメント、後置デクリメント、continue, break, return, throwの6つのことです。

(仕様よりスクショ。)

f:id:chuck0523:20150919102915p:plain

スクショの[no LineTerminator here]という部分で改行をすると、セミコロンが挿入されるとのこと。

 

以上の3つが、JavaScriptでセミコロンが自動挿入されるルールのようです。

 

まとめ

普段意識することはありませんが、調べてみると面白いですね。

ただ、1.1と2の違いが分からず、モヤモヤも残ります…。今後の仕様で変わっていくことはあるのでしょうか??

 

ただ、一つ言えることは、セミコロンはきちんと書いた方がいいということですね。

JavaScriptGoodPartsにもそのように推奨してますし、書くほうが無難です。

 

 

参考URL

分かりやすかったブログ記事

JavaScriptの行末セミコロンは省略すべきか

 

英語の勉強にもなるかもしれない記事

James Allardice - Understanding automatic semi-colon insertion in JavaScript

 

Ecmaの本家仕様

http://www.ecmascript.org/docs/tc39-2009-043.pdf

 

仕様から、セミコロン自動挿入に関して抜粋。

f:id:chuck0523:20150919091639p:plain