僕はJavaScriptでセミコロン(;)を書きません
そしてこういう風に思い込んでました
- 文末のセミコロンは常に省略可能
- JSでのセミコロンは完全に任意
それは思い違いだったようです
どうみても問題なさそうなのに、
省略でエラー・バグが出ることがあります
そのようなケースと理由を解説
このページの目次
ケース1.return文のあとで改行して値を返すとき
関数から値を返す場合です
return後に改行して返り値を書くのはダメ
▼ こういう関数で考えてみる
1 2 3 4 5 6 7 |
function add() { let a = 1, b = 2 return a + b } console.log('add : ',add()) |
▼ コンソール出力結果
1 |
add : undefined |
人間としては return a + b を返してほしいだけだけど、JSインタープリターは人間のように融通は利きません。次のように解釈してしまいます
▼ インタープリターはこう解釈する
1 2 3 4 5 6 |
function add() { let a = 1; let b = 2; return; a + b; } |
これが undefined になる理由
かならず return のあとに返り値全体・あるいはオブジェクトなどなら一部を続けて書く必要があります。return直後に改行するのはヤバいです(セミコロン関係なしに)
ケース2.関数・値の後に () で即自関数実行など
これも遭遇する場面が多いです。
関数・値の後に () で即自関数実行
これだと意味不明なので具体例を出します
▼ このようなコードを考えてみる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
let y = 0 let func = function hoge(x){ return x } (function fuga(x){ console.log('x : ', x) y = x return x })(100) console.log('func : ', func) console.log('y : ', y) |
いきなり出力結果を書いてもいいです
でも少し考えてみてください。それぞれ x, y, func の値はどのようになると思いますか?セミコロンの挙動が分からないと混乱するはずです
▼ コンソール出力結果はこうなった
1 2 3 |
x : 100 func : 100 y : 100 |
全て 100 という値になります。
インタープリター側はこう解釈する模様です
▼ インタープリターはこう補完する
1 2 3 4 5 6 7 8 9 10 11 12 13 |
let y = 0; let func = (function hoge(x){ return x; })(function fuga(x){ console.log('x : ', x); y = x; return x; })(100); console.log('func : ', func); console.log('y : ', y); |
もし値・関数のあとにセミコロンなしで () で囲まれた値・関数がある場合、それは直前の関数の引数として解釈されます。
▼ やってることは次と同じになる
- hoge関数にfuga関数を丸ごと渡す
- hoge関数内でfuga関数を返す
- 最後にそれに100を渡して実行
セミコロンがあれば func にはhoge関数が関数オブジェクトとして渡されるだけだし、fuga関数は即自関数として何事もなく実行されたことでしょう
このケースの修正例。必ずセミコロンが必要
▼ つまり次のように直せばOK
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
let y = 0 let func = function hoge(x){ return x }; /// <= この差は大きい (function fuga(x){ console.log('x : ', x) y = x return x })(100) console.log('func : ', func) console.log('y : ', y) |
しかしセミコロンの有無で処理が全く違くなります。
エラーが出るならまだ幸運な方です。
このケースだとエラーすら出てくれません
JSインタープリタを過信しすぎないことです
ただしセミコロンは必ず必要という結論にはならない
ここまでの2つの例は極端なケースです。
そして滅多に発生せず、エラーが出ることもあります。
だからセミコロンは絶対必要とまでは言い切れません。
1つめのreturn文の後で改行がないケースですが、「returnの後は即改行せず返り値または返り値の一部を書く」と意識すれば防げます。
厄介なのは2番目のケースで、即自関数を使うときは注意した方がいいかもしれません。例として出したコードのように違和感に気付くのが難しいです(その上エラーも出ない)
JSを書く時は頭の片隅で意識しておくしかないです。
もし良いアイデアがあれば教えてください。ではまた