キーワード: 識別子、実行コンテキスト、スコープ、スコープ チェーン、変数オブジェクト、アクティブ オブジェクトの理論的知識
JavaScript がスコープとスコープ チェーンをどのように管理するかを理解することが重要です。スコープ チェーン内で検出される変数オブジェクトの数が識別子の解決のパフォーマンスに直接影響するためです。識別子がスコープ チェーン内で深くなるほど、その識別子を見つけてアクセスするのに時間がかかります。スコープが適切に管理されていない場合、スクリプトの実行時間に悪影響を及ぼす可能性があります。
JavaScript コードを実行すると、JavaScript エンジンは 実行コンテキスト (実行コンテキスト) を作成します。実行コンテキスト (スコープ と呼ばれることもあります) は、コードが実行される環境を設定します。 JavaScript エンジンは、ページが読み込まれた後にグローバル実行コンテキストを作成し、その後、関数が実行されるたびに対応する実行コンテキストを作成し、最終的に実行コンテキストのスタックを構築します。現在アクティブな実行コンテキストがスタックの最上位にあります。 。
各実行コンテキストには、識別子を解析するための関連する スコープ チェーンがあります。スコープ チェーンには、実行コンテキスト スコープ内の識別子を定義する 1 つ以上の 変数オブジェクト が含まれます。グローバル実行コンテキストのスコープ チェーンには変数オブジェクトが 1 つだけあり、これにより JavaScript で使用できるすべてのグローバル変数と関数が定義されます。関数が作成される (実行されない) と、JavaScript エンジンは作成時の実行コンテキストのスコープ チェーンを関数の 内部プロパティ [[Scope]] に割り当てます。次に、関数が実行されると、JavaScript エンジンは アクティビティ オブジェクト (アクティブ オブジェクト) を作成し、初期化中にこれ、引数、名前付きパラメーター、および関数のすべてのローカル変数に値を割り当てます。アクティブなオブジェクトは実行コンテキストのスコープ チェーンの先頭に表示され、その後に関数の [[scope]] 属性内のオブジェクトが続きます。
コードを実行するとき、JavaScript エンジンは実行コンテキストのスコープ チェーンを検索することによって、変数名や関数名などの識別子を解決します。識別子を解決するプロセスはスコープの先頭から始まり、上から下の順序で進みます。
理論を検証してください関数 add(num1, num2) {
num1 num2 を返す;
}
このコードの実行が開始されると、add 関数にはグローバル変数オブジェクトのみを含む [[scope]] 属性が設定されます。以下に示すように:
add 関数を実行すると、JavaScript エンジンは新しい実行コンテキストと、これ、引数、num1、および num2 を含むアクティブ オブジェクトを作成し、アクティブ オブジェクトをスコープ チェーンに追加します。 add() 関数内で実行する場合、JavaScript エンジンは関数内の num1 識別子と num2 識別子を解析する必要があります。 var total = add(5, 10);
解析プロセスは、スコープ チェーンの最初のオブジェクト、つまり関数のローカル変数を含むアクティブなオブジェクトから始まります。オブジェクト内に識別子が見つからない場合は、スコープ チェーン内の次のオブジェクトまで検索が続行されます。識別子が見つかると、検索は終了します。
効率的なデータアクセスローカル変数は、JavaScript で最も速く読み書きできる識別子です。
良い経験則: 関数内で複数回使用される非ローカル変数は、ローカル変数として保存する必要があります。
配列とオブジェクトの場合は、頻繁にアクセスされる値を常にローカル変数に格納します。
実際、HTMLCollection オブジェクト属性にアクセスするたびに、DOM ドキュメントが動的にクエリされます。
HTMLCollection オブジェクトのメンバーに繰り返しアクセスする必要がある場合、効率的な方法は、それらを配列にコピーすることです。