困った体験
最近、JavaScriptで無名関数を使い、思わぬ落とし穴にはまりそうになった体験談についてまとめます。古くからある言語は行単位で記述する習わしでした。
文の終わりは行末であるから、セミコロンのような文の終わりを明示しなくてもよかったのです。
新しい言語は行ではなく、ブロックという考え方に変わり、文の終わりにはセミコロンで区切るようになっています。
その名残りなのか、セミコロンを省略しても文法エラーとして扱わない温情ゆたかなブラウザが多いです。
4つの例題で確認
4つの例題を1つのファイルのまとめました。それぞれの特徴を記します。check0は無名関数の文法に則った記述です。check1は無名関数の終わりを示す’}’の後のセミコロンを省略したもの。check2は’}’の後の2つの改行コードを削除したもの。最後のcheck3は’}’の後にセミコロンを挿入したものです。
<!DOCTYPE html check0.html>
<html>
<script>
calc = function (a, b) {//結果を求め、戻り値を返す
return a + b;
}; //<==== セミコロン
//<<< 無名関数の動作確認 >>>
alert(calc(1, 2)); //3が出力される
alert(calc(10, 20)); //30が出力される
</script>
</html>
//----------------------------------------------------
<!DOCTYPE html check1.html>
<html>
<script>
calc = function (a, b) {//結果を求め、戻り値を返す
return a + b;
} //<==== セミコロン忘れ
alert(calc(1, 2)); //3が出力される
alert(calc(10, 20)); //30が出力される
</script>
</html>
//----------------------------------------------------
<!DOCTYPE html check2.html>
<html>
<script>
calc = function (a, b) {//結果を求め、戻り値を返す
return a + b;
}alert(calc(1, 2)); //3が出力される(この行でエラー)
alert(calc(10, 20)); //30が出力される
</script>
</html>
//----------------------------------------------------
<!DOCTYPE html check3.html>
<html>
<script>
calc = function (a, b) {//結果を求め、戻り値を返す
return a + b;
};alert(calc(1, 2)); //3が出力される(エラーは起きない)
alert(calc(10, 20)); //30が出力される
</script>
</html>
動作結果
| check0 | 文法エラーなし |
| check1 | 文法エラーなし。18行の}の後、行末まで有効なコードがないのでセミコロンを自動補完 |
| strict版check1 | 文法エラー発生 |
| check2 | 文法エラー発生。30行、}の後に有効なコードがあるのでセミコロンは自動挿入されない |
| check3 | 文法エラーなし |
厳密な文法チェック法
check1において、厳密な文法チェックをするには、”use strict”指定にします。すると「Uncaught ReferenceError: calc is not defined at check1.html:5」のエラーが出力されるようになります。以下に改訂されたcheck1を示します。
<!DOCTYPE html check1.html>
<html>
<script>
"use strict";
calc = function (a, b) {//結果を求め、戻り値を返す
return a + b;
}
alert(calc(1, 2)); //3が出力される
alert(calc(10, 20)); //30が出力される
</script>
</html>
さいごに

曖昧なプログラミングでも文法エラーにしないで、期待通りに実行できることはありがたいことですが、check2のように冗長度をなくした時に、突然、エラーが検出されることがあります。
改行コードを削除して、ソースコードの解析されにくさをねらったときに、エラーが起きた場合には、厳格さを欠いたプログラミングを疑ってみましょう。
無名関数の定義は代入文と同等です。「代入文はセミコロンで締めくくる」と覚えておけば、セミコロンを忘れることが少なくなりそうです。
曖昧さを放っておくとセキュリティホールの原因になることがあります。できれば、曖昧な表現をなくしましょう。