JavaScript の実行コンテキストとコールスタックの詳細な説明

JavaScript の実行コンテキストとコールスタックの詳細な説明

1. 実行コンテキストとは何か

コードは特定の環境で実行されます。これを実行環境または実行コンテキストと呼びます。さまざまな実行環境に応じて、次の 3 つのカテゴリに分類できます。

グローバル実行環境: コードが最初に実行されるときのデフォルトの環境

関数実行環境: 実行フローが関数本体に入るたびに

eval実行環境: eval関数内のテキストが実行されると

2. 実行コンテキスト スタックとは何ですか?

これは「スタック」であるため、「スタック」の特性、つまり先入後出のデータ構造に準拠している必要があります。コードの一部を見てみましょう:

関数cat(a){
    もし(a<0){
        false を返します。
    }
    console.log('スタックにプッシュ:'+a);
    猫(a-1);
    console.log('ポップアウト:'+a);
}
猫(3);
// スタックにプッシュ: 3
// スタックにプッシュ: 2
// スタックにプッシュ: 1
// スタックにプッシュ: 0
// スタックをポップ: 0
// ポップ: 1
// ポップ: 2
// ポップ: 3

上記のコードの実行プロセスを分析してみましょう。

① ブラウザがロードされると、プログラムはグローバル実行コンテキストに入り、それをスタックにプッシュします(最初に入るもの、つまり最下層)。この実行コンテキストの下には関数 cat が 1 つだけあり、cat call、パラメータ 3 です。

② プログラムはcat関数に入り、つまり関数の実行コンテキストに入り、それをスタックにプッシュします(2番目に入るもの、つまり最後から2番目のレイヤー)。パラメータ3は0より大きいため、実行を継続し、「Push stack: 3」を出力します。

③プログラムは実行を継続し、関数catを呼び出し、再び新しい関数実行コンテキストに入り、パラメータa-1を使用してスタック(3番目のエントリ、最後から3番目の層)にプッシュし続け、ステップ②をループします。ここで、関数cat(a-1)が呼び出されるため、次のコード行「Pop: a」(この時点でaはまだ3です)、つまり「Pop: 3」が一時的に取り残され、スタックの最後から2番目の層に存在することに注意してください。

④ ②③を繰り返して、「Push: 2」、「Push: 1」、「Push: 0」を順に出力します。同時に、取り残される出力は、「Pop: 2(スタックの下から3番目の層)」、「Pop: 1(スタックの下から4番目の層)」、「Pop: 0(スタックの下から5番目の層)」です。

⑤ スタックの特性に応じて、残っている4つの出力項目が「スタックにプッシュ:3」、「スタックにプッシュ:2」、「スタックにプッシュ:1」、「スタックにプッシュ:0」の順に出力されます。
上記は実行コンテキストスタックの具体的な状況です。実際にコードを実際に実行していただければ、十分に理解できると思います。

3. 実行コンテキストスタック処理の詳細

関数が呼び出されるたびに、新しいコンテキストが実行されることは既に知られています。各実行コンテキストは、作成フェーズと実行フェーズの 2 つのフェーズに分かれています。作成フェーズ: プログラムが関数を呼び出すが、コードが実行されないフェーズを指します。
実行フェーズ: 変数の割り当てや関数の実行などのコード実行フェーズを指します。

1. 作成フェーズ

この段階で関数が呼び出されると、実行コンテキスト オブジェクト (executionContextObj) が作成されます。このオブジェクトには、スコープ チェーン オブジェクト (scopeChain)、変数オブジェクト (variableObject、VO と呼ばれます)、およびこのオブジェクトの 3 つのオブジェクトが含まれます。VO には、変数宣言 (variable)、関数宣言 (function)、パラメーター (arguments) などが含まれます。
これら 3 つのオブジェクトは、次の 3 つの手順で作成されます。
ステップ1: スコープチェーン(scopeChain)を初期化し、スタックメモリを割り当てる

ステップ2: パラメータ、関数、変数を作成する

ステップ3: コンテキストの「this」の値を決定する

次のコードを使用して上記の手順をさらに分析してみましょう。

関数cat(名前) {
    var a = '年々';
    var b = 関数 () {};
    this.name = 名前;
    関数c() {
        コンソールにログ出力します。
    }
    c();
}
cat('魚がいる');

このコードが関数 cat('有鱼') を呼び出すと、実行コンテキストは作成フェーズになり、コードは次のように解析されます。

cat実行コンテキストオブジェクト = {
    scopeChain: { ... }, // 1. スコープチェーンを作成し、スタックメモリを割り当てます。variableObject: { 2. 変数オブジェクトを作成します。arguments: { // 2.1 パラメータ 0 を解析します: '魚がいます',
            長さ: 1
        },
        name: '有鱼', // 2.1 パラメータを解析し、パラメータ名を作成し、パラメータを割り当てます c: function c() // 2.2 関数宣言 c を見つけ、c を属性として使用し、関数 c を値として使用します a: undefined, // 2.3 変数宣言 a を見つけ、undefined に初期化します。この段階では宣言部分のみを見て、値を割り当てません b: undefined // 2.3 変数宣言 b を見つけ、undefined に初期化します。この段階では宣言部分のみを見て、値を割り当てません },
    this: { 3. このオブジェクトを作成する this:cat('有鱼') // 3.1 この呼び出しのオブジェクトを指す name:undefined // 3.2 オブジェクトのプロパティ name は undefined に初期化される
    };
    c() //関数 c の実行コンテキストに再度入ります。cat 関数と同じですが、まだ展開されていません。}

コード分​​析を通じて、次のような結論を導き出すことができます。

①3つのステップの順序は間違えてはいけない ②VOステップでは関数宣言を先に実行し、次に変数宣言を実行する ③この段階ではパラメータのみ割り当て可能で、変数と関数は宣言のみ可能

2. 実装

この段階では、js インタープリターはコンテキスト内の関数コードを実行し、js コードを 1 行ずつ実行し、変数に値を割り当てます。
または、コードと組み合わせて分析します。

cat実行コンテキストオブジェクト = {
    スコープチェーン: { ... },
    変数オブジェクト: { 
        引数: { 
            0: 「魚がいる」
            長さ: 1
        },
        名前: 「魚がいる」 
        c: 関数c()、
        a: '年年', // 変数 a に値が割り当てられます b: 関数 b // 変数 b に値が割り当てられます },
    this: { 3. このオブジェクトを作成します this:cat('There is fish') 
        name:'有鱼' // オブジェクト属性名に値を割り当てる}
}

以上がJavaScriptにおける実行コンテキストとコールスタックの詳細な説明です。JavaScriptにおける実行コンテキストとコールスタックの詳細については、123WORDPRESS.COMの他の関連記事にも注目してください。

以下もご興味があるかもしれません:
  • JavaScript実行メカニズムの詳細な説明
  • JavaScriptの実行メカニズムを徹底的に理解する
  • JS 非同期実行の原則とコールバックの詳細
  • JavaScript での実行コンテキストと実行スタックの例の説明
  • JavaScript実行モデルの詳細な説明
  • Javascript 実行コンテキスト順序の詳細な説明
  • JavaScript モジュール エグゼキュータを手動で実装する方法
  • Javascript 非同期プロセス制御シリアル実行の詳細な説明
  • いくつかの面接の質問を使ってJavaScriptの実行メカニズムを調べる

<<:  Docker Compose を使用して nginx のロード バランシングを実装する方法

>>:  今日、今週、今月、先月のMySQLクエリデータ

推薦する

Node.js のフロントエンドとバックエンドのインタラクションによるユーザーログインの実装の実践

目次1. プロジェクト要件次にコーディングを始める1. フロントエンドページを作成する(CSSスタイ...

404エラーページを作成する際に注意すべき問題の簡単な分析

ウェブサイトを最適化するときは、エラー ページの使い方を学ぶ必要があります。たとえば、ウェブサイトに...

iOS スタイルの選択ボックスの開閉機能を実装するための純粋な CSS

1 効果デモアドレス: https://www.albertyy.com/2020/7/check...

MySQL コマンドライン操作中のエンコードの問題の詳細な説明

1. MySQLデータベースのエンコーディングを確認する mysql -u ユーザー名 -p パスワ...

Navicatを使用してクラウドサーバーデータベースにリモート接続する方法

秘密鍵を開かずにリモート サーバーのデータベースに接続するのは非常に便利です。新しい接続でデータを入...

入力ボックスの値を取得する方法のReactの例

入力ボックスの値を取得する複数の方法最初の方法は、制御されていないコンポーネントの取得です2番目の方...

NODE.JS を使用して WEBSERVER を作成する手順

目次Node.jsとはNodeJSをインストールするNode を使用して Hello World を...

Chrome Dev Tools を使用してページのパフォーマンスを分析する方法 (フロントエンドのパフォーマンス最適化)

背景開発やデバッグには Chrome Dev Tools がよく使用されますが、ページのパフォーマン...

Docker 入門インストールチュートリアル (初心者版)

ドクター紹介: Docker はコンテナ関連の技術です。簡単に言うと、さまざまなソフトウェアを実行で...

カタツムリ映画システムのDocker展開の詳細なプロセス分析

環境に関する声明ホストOS: Cetnos7.9 最小インストールdocker バージョン: 20....

Docker でローカルにイメージをインポート/保存/読み込み/削除する方法

1. Dockerはローカルイメージをインポートする場合によっては、イメージをローカルまたは別の友人...

Pure CSS と Flutter はそれぞれブリージング ライト効果を実現します (サンプル コード)

前回、非常に熱心なファンから、月を呼吸する光の効果にできるかどうか尋ねられました。月の大きさの写真が...

JavaScript で一意の ID を生成するいくつかの方法

考えられる解決策1. Math.randomは[0,1)の範囲の乱数を生成します。 //今回は生成さ...

ログインボックスのメールプロンプトを実装するネイティブJS

この記事では、登録またはログイン時に電子メール アドレスを入力する際のドロップダウン プロンプトのネ...

VMWare仮想マシンのcentosの時間が現地時間と矛盾する問題を解決する

VM Ware 仮想マシン CentOS の時刻は、次の図に示すように、現地時間と一致しません。おそ...