ホームページ > ウェブフロントエンド > jsチュートリアル > JavaScript 実行コンテキスト – JS コードが舞台裏でどのように実行されるか

JavaScript 実行コンテキスト – JS コードが舞台裏でどのように実行されるか

Mary-Kate Olsen
リリース: 2025-01-05 04:47:39
オリジナル
301 人が閲覧しました

JavaScript 実行コンテキストとは何かを理解する前に、JavaScript コードをどのように、どの環境で実行できるかを知る必要があります。

まず、JavaScript は 2 つの環境で実行できます:

  1. ブラウザ経由
  2. Node.js 経由

JavaScript コードはコンピューター上でどのように実行されるのでしょうか?

コンピューター上で JavaScript コードを作成して実行しようとすると、コードはまずブラウザーまたは Node.js に送られます。

ただし、私たちが作成した JavaScript コードは、ブラウザーや Node.js によって直接理解されるわけではありません。この時点で、どちらも組み込みの JavaScript エンジンにコードを送信します。エンジンにはさまざまな種類があります。例:

  1. Google Chrome の V8 エンジン、
  2. Mozilla Firefox の SpiderMonkey、
  3. Node.js の V8 エンジンなど

次に、JavaScript エンジンは JavaScript コードをマシンコードにコンパイルします。このマシン コードはコンピューターに送信され、コンピューターによって実行され、出力が表示されます。

プログラマーとして、この中間ステップ、つまり、JavaScript エンジンが JavaScript コードをマシンコードにコンパイルする方法をよく理解する必要があります。

それでは、JavaScript エンジンがどのように動作するかを理解する必要があります。 JavaScript エンジンは、コードをマシンコードに変換するために 2 つの方法で動作します。 1 つ目は解釈、2 つ目はコンパイルです。では、解釈と編集とは何ですか?

通訳とは何ですか?また、どのように機能するのでしょうか?

インタープリタは、高級言語で書かれたすべてのソースコードを 1 行ずつ読み取り、読み取った直後に各行をマシンコードに変換するプロセスです。コード行の読み取り中にエラーが発生した場合、プロセスはそこで停止するため、プログラマはエラーを特定しやすくなります。これにより、デバッグが簡単になります。ただし、このプロセスはコードを 1 行ずつ読み取るため、比較的遅くなります。

コンパイルとは何ですか?またその仕組みは何ですか?

コンパイルは、高級言語で書かれたすべてのソース コードを一度にマシン コードに変換するプロセスです。この場合、コードにエラーがあってもコンパイルは行われ、実行時にのみエラーが表示されます。その結果、プログラマーがエラーを特定することが難しくなり、デバッグがより困難になります。ただし、ソース コード全体が一度に機械語コードに変換されるため、このプロセスは比較的高速です。そこで次の疑問が生じます: JavaScript はコンパイルされた言語ですか、それともインタプリタ言語ですか?

JavaScript はコンパイル言語ですか、それともインタープリタ言語ですか?

当初、JavaScript は主にインタープリタ型言語と考えられていました。ただし、このプロセスは非常に時間がかかるため、最新の JavaScript エンジンは、解釈とコンパイルの両方を組み合わせた、ジャストインタイム (JIT) コンパイルとして知られる新しい技術を使用し始めました。このプロセスでは、解釈とコンパイルを組み合わせて、コードをマシンコードに変換します。その結果、古い方法と比較して、デバッグがはるかに高速かつ簡単になります。

JavaScript のジャストインタイム (JIT) コンパイルがどのように機能するかを理解するには、JavaScript の実行コンテキストを理解する必要があります。ここで、JavaScript の実行コンテキストを理解してみましょう。

JavaScript 実行コンテキスト

まず、次のコード例を見てください。

コード例

var a = 1;

function one() {
  console.log(a);

  function two() {
    console.log(b);

    var b = 2;

    function three(c) {
      console.log(a + b + c);
    }

    three(4);
  }

  two();
}

one();
ログイン後にコピー
ログイン後にコピー

出力

1
undefined
7
ログイン後にコピー

コードを実行したときに、two() 関数内で宣言される前に b 変数を出力しようとしましたが、出力は未定義でした。ただし、エラーは発生しませんでした。疑問が生じます。なぜ b 変数の値が未定義になったのでしょうか?答えは JavaScript 実行コンテキストにあります。ここで、JavaScript 実行コンテキストをさらに詳しく見ていきます。

JavaScript には 2 種類の実行コンテキストがあります:

  1. グローバル実行コンテキスト
  2. 関数実行コンテキスト

各実行コンテキストは、作成フェーズと実行フェーズという 2 つのフェーズを経ます。

グローバル実行コンテキスト

JavaScript コードを実行すると、最初にグローバル実行コンテキストが発生します。このコンテキストはまず作成フェーズを通過し、そこでいくつかのことが起こります。

作成フェーズ

  1. グローバル オブジェクトが作成されます。
  2. このオブジェクトが作成され、グローバル オブジェクトの値が割り当てられます。
  3. 変数オブジェクトが作成され、すべての関数と変数が宣言されます。変数には値として未定義が割り当てられ、関数にはそれぞれの関数への参照が割り当てられます。

作成フェーズが完了すると、グローバル実行コンテキストは次のフェーズである実行フェーズに移動し、さらに多くのステップが発生します。

実行フェーズ

  1. 作成フェーズで宣言され、未定義で初期化された変数には、それぞれの値が割り当てられます。
  2. 作成フェーズで宣言され、参照として保存された関数が呼び出され、実行されます。

関数実行コンテキスト

グローバル実行コンテキストの実行フェーズ中に参照される関数が呼び出されるとき、各関数は独自の関数実行コンテキストを作成します。グローバル実行コンテキストと同様に、関数実行コンテキストも作成フェーズを通過し、いくつかのステップが発生します。

作成フェーズ

  1. 関数のパラメーター オブジェクトが作成されます。
  2. このオブジェクトが作成され、グローバル オブジェクトの値が割り当てられます。
  3. 変数オブジェクトが作成され、すべての関数と変数が宣言されます。変数には値として未定義が割り当てられ、関数にはそれぞれの関数への参照が割り当てられます。

作成フェーズが完了すると、関数実行コンテキストは実行フェーズに移動し、そこでさらに多くのステップが発生します。

実行フェーズ

  1. 作成フェーズで宣言され、未定義で初期化された変数には、それぞれの値が割り当てられます。
  2. 作成フェーズで宣言された関数が呼び出され、実行されます。

入れ子関数の関数実行コンテキスト

他の関数内で関数が呼び出される場合、これらの関数ごとに新しい関数実行コンテキストが作成されます。各関数実行コンテキストは、作成フェーズと実行フェーズの両方を通過します。このプロセスは、別の関数内で呼び出される関数ごとに継続され、各関数はこれらのフェーズを個別に実行します。

下の図を見てみましょう。

JavaScript Execution Context – How JS Code Runs Behind the Scenes

グローバル実行コンテキストと関数実行コンテキストの両方が特定の手順を経ることがわかりました。唯一の違いは、グローバル実行コンテキストでは、最初のステップがグローバル オブジェクトを作成することであるのに対し、関数実行コンテキストでは、最初のステップは関数のパラメーター オブジェクトを作成することです。

ここで疑問が生じます: グローバル コンテキストと各関数の両方に対して実行コンテキストが作成された場合、JavaScript はこれらの実行コンテキストをどのように管理するのでしょうか?

実行スタックを使用した実行コンテキストの管理

これらのコンテキストを管理するために、JavaScript は実行スタックと呼ばれるデータ構造を使用します。実行スタックは、スタックのような方法でコンテキストを格納します。最初にグローバル実行コンテキスト、次に各関数実行コンテキストが続きます。すべての実行コンテキストがスタックに格納されると、JavaScript はスタックの先頭から順にそれらを 1 つずつ処理します。

let と const によるスコープ指定

グローバル スコープまたは関数スコープ内で let または const を使用して変数を宣言する場合、これらの変数は作成フェーズ中に変数オブジェクトに格納されず、未定義で初期化されないことに注意することが重要です。代わりに、これらの変数は実行フェーズで直接宣言され、その値が割り当てられます。

次のコード例を考えてみましょう:

コード例

var a = 1;

function one() {
  console.log(a);

  function two() {
    console.log(b);

    var b = 2;

    function three(c) {
      console.log(a + b + c);
    }

    three(4);
  }

  two();
}

one();
ログイン後にコピー
ログイン後にコピー

このコードを実行すると、ReferenceError が発生します。これは、変数 b を宣言する前に変数 b の値を出力しようとしており、 b は const を使用して宣言されているため、通常の変数とは異なる動作をするためです。 const または let で宣言された変数は、作成フェーズ中に変数オブジェクトに格納されません。そのため、値が割り当てられる前にアクセスしようとするとエラーが発生します。

結論

JavaScript がどのように動作し、実行コンテキストのフェーズで何が起こるかについてのこの説明で、より明確に理解していただければ幸いです。次のレッスンでは、別の JavaScript トピックを検討します。

GitHub や Linkedin で私とつながることができます。

以上がJavaScript 実行コンテキスト – JS コードが舞台裏でどのように実行されるかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート