ホームページ > 記事 > ウェブフロントエンド > フロントエンドの上級基礎(2):実行コンテキストの詳細図
JS学習の初期段階や面接などで、評価変数の改善に関する質問によく遭遇します。たとえば、より単純なものから始めましょう。
console.log(a); // 这里会打印出什么? var a = 20;
今回はこの例を無視して、JavaScript の最も基本的でありながら最も重要な概念である実行コンテキスト (実行コンテキスト) を最初に紹介しましょう。
コントローラーが実行可能コードに切り替わるたびに、コントローラーは実行コンテキストに入ります。実行コンテキストは、スコープを形成する現在のコードの実行環境として理解できます。 JavaScript の実行環境には大きく分けて 3 つの状況があります。
1. グローバル環境: JavaScript コードは実行時に最初にこの環境に入ります
2. 関数環境: 関数が呼び出されて実行されると、コードを実行するために現在の関数に入ります
3.eval
JavaScript プログラムでは必然的に複数の実行コンテキストが生成されます。前の記事で述べたように、JavaScript エンジンはそれらをスタック方式で処理します。スタックの最下位は常にグローバル コンテキストであり、スタックの最上位は現在実行中のコンテキストです。
コードの実行中に上記の 3 つの状況が発生すると、実行コンテキストが生成され、スタックに配置され、スタックの一番上のコンテキストが実行された後、スタックから自動的に飛び出します。このプロセスをより明確に理解するために、次の例と図に基づいて説明します。
var color = 'blue'; function changeColor() { var anotherColor = 'red'; function swapColors() { var tempColor = anotherColor; anotherColor = color; color = tempColor; } swapColors(); } changeColor();
実行コンテキスト グループを処理するスタックを表すために ECStock を使用します。最初のステップはグローバル コンテキストをスタックにプッシュすることであることが簡単にわかります。
グローバル コンテキストがスタックにプッシュされた後、その中の実行可能コードは、changeColor() に遭遇するまで実行を開始します。この文は、独自の実行コンテキストを作成するために関数 changeColor をアクティブ化します。そのため、2 番目のステップはプッシュです。 changeColor の実行コンテキストをスタックに追加します。
changeColor のコンテキストがスタックにプッシュされた後、コントローラーはその中の実行可能コードの実行を開始し、swapColors() に遭遇した後に実行コンテキストをアクティブにします。したがって、3 番目のステップでは、swapColors の実行コンテキストをスタックにプッシュします。
swapColors の実行可能コードには、実行コンテキストを生成できる他の状況がないため、このコードは正常に実行され、swapColors のコンテキストがスタックからポップされます。
swapColors の実行コンテキストがポップアップした後、changeColor の実行可能コードは実行され続け、他の実行コンテキストは実行が正常に完了した後にポップアップします。このように、ECStack にはグローバル コンテキストのみが存在します。
グローバル コンテキストは、ブラウザ ウィンドウが閉じられた後にポップされます。
注: 関数内で return が発生すると、実行可能コードの実行が直接終了する可能性があるため、現在のコンテキストはスタックから直接ポップされます。
このプロセスを詳細に理解した後、実行コンテキストに関するいくつかの結論を要約できます。
1. 単一スレッド
2. 同期実行、スタックの最上位のコンテキストのみが実行され、他のコンテキストは待機する必要があります
3. ブラウザーの起動時にスタックからポップされるグローバル コンテキストは 1 つだけです。は閉じられています
4. 関数実行コンテキストの数に制限はありません
5. 関数が呼び出されるたびに、それが呼び出された関数自体であっても、その関数に対して新しい実行コンテキストが作成されます。
実行コンテキストの理解を強化するために、例の進化を描いてみましょう。これは単純なクロージャーの例です。
function f1(){ var n=999; function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999
f1 の実行可能コード内では f1 の関数 f2 が呼び出されて実行されないため、f1 の実行時に f2 は新しいコンテキストを作成せず、結果が実行されるまで新しいコンテキストは作成されません。具体的な進化の過程は以下の通りです。