もじら組フォーラムで書いたことを再掲。以下 JavaScript といった場合 JScript などは含まないものとする。
ECMAScript 3 で function
キーワードが使われる構文には FunctionDeclaration
[LINK] と FunctionExpression
[LINK] があり、以下のように定義されている。
FunctionDeclaration
function
Identifier
(
FormalParameterList
opt
)
{
FunctionBody
}
FunctionExpression
function
Identifier
opt
(
FormalParameterList
opt
)
{
FunctionBody
}
FunctionBody
SourceElements
Program
SourceElements
SourceElements
SourceElement
SourceElements
SourceElement
SourceElement
Statement
FunctionDeclaration
これをみればわかるとおり、FunctionDeclaration
はプログラム直下か関数本体の直下にしか置けない。下の例でいうと (1) は問題ないが (2) は ECMAScript としては正しくないということだ。(2) の場合 g
は FunctionExpression
とみなされるのではと思うかもしれないが、ExpressionStatement
[LINK] を function
キーワードで開始することはできないのでそれも成り立たない。
// (1)
function f() {
function g() {}
}
// (2)
function f() {
do {
function g() {}
} while (false);
}
しかし、JavaScript ではバージョン 1.5 から Function Expression Statements という機能が追加され、通常の文が置ける場所ならどこでも関数を定義できるようになった (すなわち JavaScript では (2) も正しいコードである) 。ここではこれを仮に FunctionStatement
と呼ぶことにする。
FunctionStatement
function
Identifier
opt
(
FormalParameterList
opt
)
{
FunctionBody
}
FunctionDeclaration
と FunctionStatement
の最大の違いは処理されるタイミングである。FunctionDeclaration
はコンパイル時に処理されるその宣言が含まれる関数 (宣言がトップレベルにある場合はプログラム全体) の実行に先立って処理されるが FunctionStatement
は実行時に処理される。また、FunctionExpression
との違いとして、FunctionExpression
の Identifier
は FunctionBody
内でのみ有効だが、FunctionStatement
では文の評価後にその Identifier
を使って関数を参照できるようになることが挙げられる。
以上の特徴から、if 文を使った関数定義の振り分けなどもできる。
// (3)
var condition = true;
if (condition) {
function f() {
return true;
}
} else {
function f() {
return false;
}
}
alert(f()); // JavaScript (Firefox など) では true
また、
セコメントをする