Function Expression Statements
2005-12-10


もじら組フォーラムで書いたことを再掲。以下 JavaScript といった場合 JScript などは含まないものとする。

JavaScript の function

ECMAScript 3 で function キーワードが使われる構文には FunctionDeclaration[LINK]FunctionExpression[LINK] があり、以下のように定義されている。

FunctionDeclaration
function Identifier ( FormalParameterListopt ) { FunctionBody }
FunctionExpression
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
FunctionBody
SourceElements
Program
SourceElements
SourceElements
SourceElement
SourceElements SourceElement
SourceElement
Statement
FunctionDeclaration

これをみればわかるとおり、FunctionDeclaration はプログラム直下か関数本体の直下にしか置けない。下の例でいうと (1) は問題ないが (2) は ECMAScript としては正しくないということだ。(2) の場合 gFunctionExpression とみなされるのではと思うかもしれないが、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 Identifieropt ( FormalParameterListopt ) { FunctionBody }

FunctionDeclarationFunctionStatement の最大の違いは処理されるタイミングである。FunctionDeclarationコンパイル時に処理されるその宣言が含まれる関数 (宣言がトップレベルにある場合はプログラム全体) の実行に先立って処理されるが FunctionStatement は実行時に処理される。また、FunctionExpression との違いとして、FunctionExpressionIdentifierFunctionBody 内でのみ有効だが、FunctionStatement では文の評価後にその Identifier を使って関数を参照できるようになることが挙げられる。

以上の特徴から、if 文を使った関数定義の振り分けなどもできる。

// (3)
var condition = true;

if (condition) {
  function f() {
    return true;
  }
} else {
  function f() {
    return false;
  }
}

alert(f()); // JavaScript (Firefox など) では true

また、


続きを読む

[JavaScript]

コメント(全2件)
コメントをする


記事を書く
powered by ASAHIネット