TIL 9. JS役割ドメインと役割ドメインチェーン


JavaScriptのスキャンについて説明しましょう。この文章はCore JavaScriptに基づいて書かれています。

scope


scopeは識別子の有効範囲です.
Execution Context vs Scope
The first important thing to clear up is that context and scope are not the same.
Every function invocation has both a scope and a context associated with it. Fundamentally, scope is function-based while context is object-based. In other words, scope pertains to the variable access of a function when it is invoked and is unique to each invocation. Context is always the value of the this keyword which is a reference to the object that “owns” the currently executing code.

outerEnvironmentReference


識別子の有効範囲を内側から外側に順に検索します.そして、それを可能にしたのがLexicalEnvironmentの2番目の収集資料OuterEnvironmentReferenceです.
outerEnvironmentReferenceは、現在呼び出されている関数宣言時のLexicalEnvironmentを参照します.
宣言動作が実際に発生した時点は、呼び出しスタック内の実行コンテキストがアクティブになっているだけです.関数を宣言または定義する動作自体は1つのコードにすぎないため、すべてのコードは実行コンテキストがアクティブなときに実行されます.
outerEnvironmentReferenceは接続リスト形式を示します.宣言ポイントのLexicalEnvironmentを検索し続けると、最後にグローバルコンテキストが表示されます.最近の要因から順番に近づくしかない.
図に示すように、呼び出された関数に入るにつれて規模は徐々に小さくなり、スキャンチェーンを介してアクセス可能な変数の数は増加します.つまり、一番奥にあるほど、より多くの変数に近づくことができます.
variableshadown:この構造特性により、複数のscopeで同名識別子を宣言する場合、scopeチェーンで最初に発見された識別子に無条件にアクセスできます.
block scope
ifelseブロックはscopeを単独で作成しますが、callスタックにスタックされません.コンテキストを実行するcall stackとして保持します.
try&catchの場合、catchにはパラメータ値としてエラーを受信して開始する個別のcatch scopeがあります.

scope chain


JAvascriptエンジンは、global execution contextとその前の関数のscopeプロファイルを各scopeにリスト形式で順次格納します.
スキャンチェーンは、オブジェクト(グローバルオブジェクトを除く)のプロパティ、すなわち変数ではなく、識別子(グローバルオブジェクトを除く)で識別子を検索するメカニズムです.
javascript does this internally to search it in other Outer Environment until they found that variable.
Everyone can access the Scope in the Global Execution Context.
JavaScriptは、対応する変数が見つかるまで外部環境で内部検索を行います.また,外部scopeから内部scopeの変数にアクセスすることはできない.
エンジンはスキャンチェーンでLexicalScopeを確認します.このようにリスト順に検索されるため、スキャンチェーンと呼ばれる.最後まで検索に失敗した場合、参照エラーが発生します.
例:奇妙な変数を参照
const a = "Hello";

const bar = () => { 
	const c = "Hello c";
    // (3)
    console.log(a)
    console.log(b)
    console.log(c)
}; 

const foo = ()=>{ 
	bar() 
    const b = "Hello b";
    // (2)
    console.log(a)
    console.log(b)
    console.log(c)
}; 

foo(); 

// (1)
console.log(a)
console.log(b)
console.log(c)
すべての関数が変数a,b,cに近づいている.またjavascript engineの原則によれば,このコードには3つのエラーがある.
(1) global execution context
変数aはconsoleです.log関数でHelloに良く出力されます.しかし、変数bとcの場合、エラーのみが発生します.
Uncaught ReferenceError : b is not defined
Uncaught ReferenceError : c is not defined
(2)foo関数の実行コンテキスト
変数aとbはよく出力されている.ただし、変数cはエラーとともに出力されません.
Uncaught ReferenceError : c is not defined
(3)bar関数の実行コンテキスト
変数aとbとcはいずれも良好に出力される.

グローバル変数を抑制します。


コードのセキュリティを確保するためには、グローバル変数の使用を最小限に抑える必要があります.変数呼び出しが重複しないように、できるだけ異なる実行コンテキストを作成します.