本頁の目次 目次 次頁: 14_Program 前頁: 12_Statements
function
Identifier ( FormalParameterListopt ) { FunctionBody }function
Identifieropt ( FormalParameterListopt ) { FunctionBody }生成規則 FunctionDeclaration : function
Identifier ( FormalParameterListopt ) { FunctionBody } は関数宣言のために次のように処理される:
生成規則 FunctionExpression : function
( FormalParameterListopt ) { FunctionBody } は次のように評価される:
生成規則 FunctionExpression : function
Identifier ( FormalParameterListopt ) { FunctionBody } は次のように評価される:
new
Object() によるものであるかのように、新しいオブジェクトを生成する。NOTE FunctionExpression 内の Identifier は、 FunctionExpression の FunctionBody の内部から参照が可能で、関数にそれ自身の再帰的呼び出しを許可する。しかしながら、 FunctionDeclaration とは異なり、 FunctionExpression 内の Identifier を参照はできず、 FunctionExpression を閉じるスコープに影響しない。
生成規則 FunctionBody : SourceElements は次のように評価される:
関数オブジェクト生成の処理を述べるため、2 つの定義を要する:
FunctionBody 文法生成規則を用いる 2 者は、次のうちの一つが真であるとき、等しいものであると定義される:
NOTE Function コンストラクタ呼び出し(15.3.1, 15.3.2) から取得される FunctionBody を用いる 2 者は、けして等しいとはみなされない。2 つの異なる eval 呼び出しから取得される FunctionBody を用いる 2 者も、それが同じ引数を渡されていたとしても、等しいとはみなされない。
2 つ以上の Function オブジェクトが結合しているとき、それらは次の特殊な振る舞いを持つ:
NOTE 互いに結合した 2 つ以上のオブジェクトは、それらが異なる内部プロパティを持っているかもしれない点を除いて、事実上判別できない。本仕様において異なってもよいような内部プロパティこそが [[Scope]] である。結合されたオブジェクトは、正確な仕様技術用の道具としてこの標準の中で使用される。それは、実際の Function オブジェクトの実装法のガイドラインに使用されることを意図しない。もっと言えば、実際に実装は、2 つ以上の結合された Function オブジェクトの [[Scope]] プロパティの差が外部的に観測されず、その場合結合された Function オブジェクトの組を作らずに同じ Function オブジェクトを再使用するという時を検知するかもしれない。この標準は単に ECMAScript プログラムにみられる振る舞いの仕様であるので、これは合法的な最適化である。
FormalParameterList で指定される選択的なパラメータのリスト、FunctionBody で指定される本文、Scope で指定されるスコープ連鎖を与えられ、Function オブジェクトは次のように生成される:
new
Object() により生成されるかのように、新しいオブジェクトを生成する。NOTE prototype プロパティは、各関数に自動的に生成され、関数がコンストラクタとして利用される可能性を許可する。
ステップ 1 は実装に、B が A に依存しないところの入れ子の関数 B を持つ関数 A の一般的なケースの最適化を許可する。このケースでは実装は B のために A が呼出される度に毎回新しいものを生成する代わりに同じオブジェクトの再利用を許可される。ステップ 13 はこの最適化を選択的にする; これを実装しないことを選択する実装は、ステップ 2 に進む。
例えば、このコード:
function A() { function B(x) {return x*x;} return B; } function C() { return eval("(function (x) {return x*x;})"); } var b1 = A(); var b2 = A(); function b3(x) {return x*x;} function b4(x) {return x*x;} var b5 = C(); var b6 = C();
の中で、実装は、b1 と b2 の結合を許可される。だが要求はされない。実際、それらの [[Scope]] プロパティ間の違いを検知する方法がないので、b1 と b2 を同じオブジェクトに作成してもよい。一方、実装はソースコードの等しくない(13.1.1) b3 と b4 を結合してはならない。また実装は、2 つの異なる eval 呼び出しで生成されるためにソースコードの等しくない b5 と b6 も結合してはならない。
実際、それは、それらの [[Scope]] プロパティ間に違いが見られないことを実装が証明でき、それで 1 つのオブジェクトを再使用できる時にのみ、2 つの Function オブジェクトの結合に生産的だろう。このポリシーに従うことによって、実装は、それ自体に結合しているオブジェクトの空虚なケースに遭遇するだけになる。
Function オブジェクト F の [[Call]] プロパティが呼出されるとき、次のステップが取られる:
this
値を渡す。throw
ならば、Result(2).value を投げる。Function オブジェクト F の [[Construct]] プロパティが呼出されるとき、次のステップが取られる:
this
値として提供し、引数値として [[Construct]] に渡された引数リストを提供する。