良い質問。何が起こっているか見てみましょう:
dummy()
関数呼び出しです(11.2.3)
手順 8 を参照してください。「func で [[Call]] 内部メソッドを呼び出し、thisValue を this 値として指定し、リスト argList を引数値として指定した結果を返します。」を参照してください。
そうdummy.[[Call]]
呼ばれます。13.2.1 ( ) に移行します[[Call]]
。
funcCtx を、F の [[FormalParameters]] 内部プロパティの値、渡された引数 List args、および 10.4.3 で説明されている this 値を使用して、関数コードの新しい実行コンテキストを確立した結果とする。
10.4.3dummy()
で説明されているように、実際には新しい実行コンテキストを作成します。
の関数コードが実行されたので、 NewDeclarativeEnvironmentdummy
は 10.4.3 パスのステップ #5 に従って作成されます。dummy.[[Scope]]
dummy
は への単なる参照でbar
あり、 も同様dummy.[[Scope]]
ですbar.[[Scope]]
。Andbar.[[Scope]]
は実行された瞬間foo
(1 行前) に定義されており、( を含む) 内の関数宣言ごとに自然に関数が作成されますbar
。
bar.[[Scope]]
[global environment]
本質的にはand [foo VE]
(Variable Environment)からなるチェーンです。そのため、実行時に独自の VE を作成し、foo の VE をアウターとして使用します。スコープ チェーンが で構成されるようになり[global environment]->[foo VE]->[bar VE]
ました。
x
var の VE でy
見つかり、bar の VE で見つかり、アラートが引数として正常に受信3
されます:)
しかし、元の質問に答えるために、はい、「関数コードの入力」は次の場合に発生します
(function(){ ... })();
そしての場合
f();
どちらも基本的に関数の [[Call]] を呼び出すためです。1 つ目はCallExpression
が後にFunctionExpression
続くArguments
であるのに対し、2 つ目はCallExpression
が後にIdentifier
続くArguments
です。
どちらも、実行される内部 [[Call]] メソッドを持つ関数オブジェクトに解決されます。