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