JavaScript無名関数の文法

困った体験

最近、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のように冗長度をなくした時に、突然、エラーが検出されることがあります。

改行コードを削除して、ソースコードの解析されにくさをねらったときに、エラーが起きた場合には、厳格さを欠いたプログラミングを疑ってみましょう。

無名関数の定義は代入文と同等です。「代入文はセミコロンで締めくくる」と覚えておけば、セミコロンを忘れることが少なくなりそうです。

曖昧さを放っておくとセキュリティホールの原因になることがあります。できれば、曖昧な表現をなくしましょう。

 

コメントを残す

下記項目は必須ですがメールアドレスは公開されません。名前はニックネームをお使いください。

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください