この記事では、JavaScript の実行コンテキストについて説明し、思考の質問を共有します。思考の質問の分析を通じて、実行コンテキストについての理解がさらに深まることでしょう。
これまでの記事では、実行コンテキストの 3 つの重要なメンバー、変数オブジェクト、スコープ チェーン、this について詳しく理解しました。まず4つの記事の内容をまとめて、散在していた知識を集約し、シンプルにまとめました。前回の記事からここに来た人がいるかわかりませんが、前回の記事で疑問が残りました。その疑問を分析することで、実行コンテキストをより深く理解していきます。
ケースを少し複雑にするために、いくつかの修正が加えられていますが、元の質問で検討された点は変更されていません。
function func(value){ getValue = function(){ console.log(value); }; return this } function getValue(){ console.log(5); } Func(1).getValue(); //为什么是1呢?
グローバル コードを実行し、グローバル実行コンテキストを作成すると、グローバル コンテキストが実行コンテキスト スタックにプッシュされます
ECStack = [ globalContext ];
グローバル コンテキストを初期化します
globalContext = { VO: { func: reference to function func(){}, getValue: reference to function getValue(){} }, Scope: [globalContext.VO], this: globalContext.VO //全局上下文 }
グローバル コンテキストを初期化すると 2 つの関数が同時に作成されるため、その親スコープ チェーンも内部プロパティ [[scope]]
func.[[scope]] = [ globalContext.VO ]; getValue.[[scope]] = [ globalContext.VO ];
に保存されます。時刻、コードの実行が開始されます。最後のステートメントが実行されると、最初に func 関数が実行され、ステップバイステップの func 関数実行コンテキストが作成されます。
Copy function [[scope ]] 属性を使用してスコープ チェーンを作成します
引数を使用してアクティブ オブジェクトを作成します
funcContext = { AO: { arguments: { // 数组 0: 1, length: 1 } }, Scope: [AO, globalContext.VO], this: undefined }
関数実行コンテキストを作成し、実行コンテキスト スタックにプッシュします。
ECStack = [ funcContext, globalContext ];
関数が実行を開始します。これが、
なぜ最終出力が 1であるのかを知るための鍵です。最初の文の代入操作、次に実行コンテキストに沿って変数 getValue を見つける必要があります。次に funcContext のスコープを見てみましょう。まず funcContext.AO を見つけます。明らかに getValue 属性は存在しません。次にスコープ チェーンに沿って調べて見つけます。 globalContext.VO、getValueが見つかりました。このとき、グローバルスコープのgetValue属性が再割り当てされます。割り当てられるのは新しいバージョンの関数であり、関数スコープが再作成され、この親が割り当てられます新しい getValue 関数が再割り当てされます。レベル スコープ チェーンは内部プロパティ [[scope]]:
getValue .[[scope]] = [ funcContext.AO, globalContext.VO ];
ECStack = [ globalContext ];
実行を続行
Func(1).getValue()、前半は未定義を返します。このとき、システムは暗黙的にグローバル変数オブジェクトに変換し、そこから getValue 属性を見つけます。グローバル変数オブジェクト。この時点で、getValue はもう当時の少年ではないことがわかりました。新しい getValue の関数実行コンテキストがスタックにプッシュされました: , スコープに沿って探します。getValueContext.AO にはそのような属性はありません。検索を続けて funcContext.AO を見つけます ( [推奨学習: 以上がJavascript の実行コンテキストについて説明する記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。getValueContext = { AO: { arguments: { // 数组 length: 0 } }, Scope: [ AO, funcContext.AO, globalContext.VO ], this: undefined } ECStack = [ getValueContext, globalContext ];
Note!
)。値が見つかった場合は、仮パラメータに入力すると、対応する値が出力されます。関数の実行後、getValueContext と globalContext がスタックからポップされて次々に破棄され、コードが完成します。この映画では、単純だが単純ではない例を使用して、前の 4 つの記事を結び付け、JS コードが実行されるときの実行コンテキストを完全に分析します。この作業プロセスをより深く理解することができます。しかし、注意深い学生は、上記の例では、getValue 関数の実行中に、属性値を見つける (位置をマークする) ステップから、その時点で明らかに func 関数が実行されていることを発見したでしょうか。その実行コンテキストは解放されました。スタック、なぜまだその実行コンテキストから value 属性を見つけることができるのでしょうか?これは実際にはクロージャ生成の原理です。次の記事では、引き続きこの例を使用してクロージャ生成の原理を学習します。