JavaScriptにはScope(スコープ)、Scopechain(スコープチェーン)、ExecuteContext(実行コンテキスト)、ActiveObject(アクティブオブジェクト)、DynamicScope(ダイナミックスコープ)、Closure(クロージャ)といった概念があります。これらの概念を理解するために、静的と動的という 2 つの側面から分析します。
まず、例として簡単な関数を作成します。
2 つの仮パラメータを持つ add 関数を定義します。
静的アスペクト:
追加関数を作成するとき、JavaScript エンジンは追加関数のスコープ チェーンを作成します。このスコープ チェーンはグローバル コンテキストを指します。図で表すと以下のようになります。
上の図からわかるように、add 関数が作成された時点で、スコープ チェーンはすでに作成されているため、関数の作成時に関数のスコープ チェーンが作成されていると結論付けることができます。動的ではなく。動的実行時に何が起こるかを見てみましょう。
動的側面:
追加関数が実行されると、JavaScript は追加関数の実行時に必要なすべての情報を含む実行コンテキストを作成します。実行コンテキストには独自のスコープ チェーンもあります。関数が実行されると、JavaScript エンジンは最初に追加関数のスコープ チェーンから実行コンテキストのスコープ チェーンを初期化し、次に JavaScript エンジンはすべてを含むアクティブ オブジェクトを作成します。ローカル変数、パラメーター、関数実行時のこの変数とその他の変数。
追加関数の動的実行中に何が起こるかを明確に説明するには、次の図を使用します。
上の図からわかるように、実行コンテキストは関数の実行時に作成され、同時にスコープによって参照されます。実行コンテキストのチェーン。したがって、実行コンテキストとアクティブ オブジェクトは両方とも動的概念であり、実行コンテキストのスコープ チェーンは関数スコープ チェーンによって初期化されるという結論を導き出すことができます。
上記の関数スコープと実行コンテキストスコープについて次に、JavaScript で with ステートメント、try-catch の catch 句、および eval メソッドを使用する場合、JavaScript エンジンは動的スコープの問題について説明します。実行コンテキストのスコープを変更します。例を通して見てみましょう:
最後に、JavaScript の最も神秘的なクロージャを見てみましょう。JavaScript のクロージャは、実際には関数の実行時に作成されます。
上記の assignEvents 関数が実行されると、クロージャが作成され、このクロージャは、assignEvents スコープ内の id 変数を参照します。id は、id が消滅したときにスタックに保存されます。関数が実行された後、再度参照するにはどうすればよいでしょうか?明らかに、JavaScript はここで別のアプローチを採用しています。 JavaScript がクロージャを実装する方法を見てみましょう。 assignEvents 関数が実行されると、JavaScript エンジンは assignEvents 関数実行コンテキストのスコープ チェーンを作成します。このスコープ チェーンには、assignEvents の実行時にアクティブなオブジェクトが含まれます。また、同時にクロージャも作成されます。クロージャのスコープ チェーンは、assignEvent が実行されるときにアクティブ オブジェクトも参照します。そのため、assignEvents が実行されると、独自の実行コンテキストのスコープ チェーンはアクティブ オブジェクトを参照しなくなりますが、クロージャは引き続きアクティブ オブジェクトを参照します。 assignEvents ランタイムに対応します。これは、JavaScipt 内のクロージャ メカニズムを説明します。次の図は、上記の assignEvents 関数の実行時の状況を明確に説明するために使用できます。
上記からわかるように、assignEvents 関数が実行された後、document.getElementById("save-btn").onclick がクロージャを参照するため、ユーザーが save-btn をクリックするとクロージャが実行されます。がトリガーされた場合、クロージャが実行されたときの状況を見てみましょう。前述したように、JavaScript のクロージャは実際には関数であるため、クロージャが実行されるときの状況は、関数が実行されるときと同じです。次の図は、上記の onclick イベントに関連付けられたクロージャを明確に示しています。
上の図からわかるように、JavaScript エンジンは最初にクロージャの実行コンテキストを作成し、次にクロージャ スコープ チェーンを使用してクロージャの実行コンテキスト スコープ チェーンを初期化し、最後にクロージャの実行コンテキスト スコープ チェーンを初期化するときに、対応するアクティブ オブジェクトを配置します。クロージャが実行されると、スコープのフロントエンドに入ることで、クロージャが関数であるというアサーションがさらに検証されます。