13 関数定義

構文

FunctionDeclaration :
    function Identifier ( FormalParameterListopt ) { FunctionBody }
FunctionExpression :
    function Identifieropt ( FormalParameterListopt ) { FunctionBody }
FormalParameterList :
    Identifier
    FormalParameterList , Identifier
FunctionBody :
    SourceElementsopt

生成規則

関数定義の生成規則

FunctionDeclaration : function Identifier ( FormalParameterListopt ) { FunctionBody }
  1. FormalParameterListoptで指定される引数とFunctionBodyで指定される本体とともに13.2で示されるように新しいFunctionオブジェクトを生成した結果を返す。Scopeとして実行中の実行コンテキストのVariableEnvironmentを渡す。strictコード内にFunctionDeclarationが含まれるか、FunctionBodyがstrictコードであればStrictフラグとしてtrueを返す

生成規則

関数命名の生成規則

FunctionExpression : function ( FormalParameterListopt ) { FunctionBody }
  • FormalParameterListoptで指定される引数+FunctionBodyで指定される本体とで新しいFunctionオブジェクトを生成した結果を返す
  • Scopeとして実行中コンテキストのレキシカル環境を渡す
  • strictコード内にFunctionExpressionが含まれる or FunctionBodyがstrictコードであればStrictフラグ true

生成規則

関数命名の生成規則

FunctionExpression : function Identifier ( FormalParameterListopt ) { FunctionBody }

6つのプロセスを経て評価される

  1. 実行中コンテキストのレキシカル環境を引数として渡す
  2. envRecをfuncEnvの環境レコードとする
  3. IdentifierのString値が引数のenvRecのCreateImmutableBinding具象メソッド呼び出し
  4. 以下の流れ
    1. FormalParameterListoptで指定される引数+FunctionBodyで指定される本体とで新しいFunctionオブジェクトを生成した結果を返す
    2. Scopeとして実行中コンテキストのレキシカル環境を渡す
    3. strictコード内にFunctionExpressionが含まれる or FunctionBodyがstrictコードであればStrictフラグ true
  5. IdentifierのString値とclosureが引数のenvRecのCreateImmutableBinding具象メソッド呼び出し
  6. closureを返す

注釈

  • 再帰呼出しが可能なようにFunctionExpressionの識別子はFunctionExpressionのFunctionBody内から参照されうる
  • FunctionExpression内のIdentifierはFunctionExpressionを取り囲むスコープからは参照されない

生成規則

ソースコードの生成規則

FunctionBody : SourceElementsopt
  1. ソースコードの評価基準
    1. strictモードコードが含まれていたらstrictモードコードになる
    2. strictモードコードであるなら次のステップはstrictモードコード
    3. そうでないなら次のステップは非strictモードコード
  2. SourceElementsが存在するならSourceElementsの評価結果
  3. それ以外の場合は(normal,undefined,empty)

13.1 strictモードの制限

  • strictモードのFunctionDeclarationまたはFunctionExpressionのFormalParameterList内にIdentifierが2回以上現れる場合は、SyntaxError

13.2 Functionオブジェクトの生成

  • FunctionParameterListによって指定されるオプションの引数リスト、FunctionBodyによって指定されるbody Scopeによって指定されるレキシカル環境、BooleanフラグStrictが与えられると、Functionオブジェクトが構築される
  • 20くらいプロセスがあるのでなんか長い

  1. ネイティブECMAScriptオブジェクトFを作成
  2. Fの内部メソッド設定 (8.12)
  3. Fの[[Class]]内部プロパティをFunctionに設定
  4. Fの[[Prototype]]設定 (15.3.3.1)
  5. Fの[[Get]]設定 (15.3.5.4)
  6. Fの[[Call]]設定 (15.2.1)
  7. Fの[[Construct]]設定 (15.2.2)
  8. Fの[[HasInstance]]設定 (15.3.5.3)
  9. Fの[[Scope]]設定
  10. namesを左から右へのListとする。パラメータがないなら空リスト
  11. Fの[[FormalParameters]]をnamesに設定
  12. Fの[[Code]]をFunctionBodyに設定
  13. Fの[[Extensible]]をtrue
  14. lenをパラメータの数にする 0でも可
  15. Fの[[DefineOwnProperty]]の呼び出し({[[Value]]: len, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false}, false)
  16. new Object()で新しいオブジェクトprotoを生成する
  17. protoの[[DefineOwnProperty]]の呼び出し({[[Value]]: F, { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}, false)
  18. Fの[[DefineOwnProperty]]の呼び出し({[[Value]]: proto, { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}, false)
  19. strictがtrueだったら以下をやる
    1. throwerを[[ThrowTypeError]]にする
    2. Fの[[DefineOwnProperty]]の呼び出し({[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, false)
    3. Fの[[DefineOwnProperty]]の呼び出し({[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, false)
  20. Fを返す

13.2.1 [[Call]]

  • FunctionオブジェクトFに対する[[Call]]内部メソッドがthis値と引数のリストとともに呼び出されると、以下のステップが実行

  1. funcCtxを関数コードに対する新たな実行コンテキストを設置した結果とする
  2. resultをFunctionBodyを評価した結果とする
    1. [[Code]]内部プロパティがない、空のFunctionBodyなら(normal,undefined,empty)
  3. 実行コンテキスト復元
  4. result.type throwならresult.valueをスロー
  5. result.type returnならresult.valueを返す
  6. でなければresult.typeはnormalでなければならず、undefinedを返す

13.2.2 [[Construct]]

  • FunctionオブジェクトFに対する[[Construct]]内部メソッドが空となる可能性のある引数リストとともに呼び出されると、以下のステップが実行

  1. objをネイティブECMASriptオブジェクトとする
  2. objの内部メソッド設定 (8.12)
  3. objの[[Class]]内部プロパティをObjectに設定
  4. objの[[Extensible]]をtrue
  5. protoをFの[[Get]]内部プロパティを設定
  6. Type(proto)がObjectなら[[Prototype]]内部プロパティをprotoにする
  7. Type(proto)がObjectでなければ[[Prototype]]内部プロパティをプロトタイプオブジェクトにする (15.2.4)
  8. objをthis値として与えて、resultをFの[[Call]]内部プロパティを呼び出した結果とする
  9. Type(result)がObjectならreturnを返す
  10. objを返す

13.2.3 [[ThrowTypeError]]

  • [[ThrowTypeError]]オブジェクトは以下のように一度だけ定義される唯一の関数オブジェクトである

  1. FをネイティブECMASriptオブジェクト
  2. Fの内部メソッド設定 (8.12)
  3. Fの[[Class]]内部プロパティをFunctionに設定
  4. Fの[[Prototype]]設定 (15.3.3.1)
  5. Fの[[Call]]設定 (13.2.1)
  6. Fの[[Scope]]をグローバル環境
  7. Fの[[FormalParameters]]を空のリスト
  8. Fの[[Code]]を無条件にTypeError例外をスローしてそれ以外は何もしないFunctionBodyに設定
  9. Fの[[DefineOwnProperty]]の呼び出し({[[Value]]: 0, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false}, false)
  10. Fの[[Extensible]]をfalse
  11. [[ThrowTypeError]]をF