Scopeの場合

11479 ワード

スコフ?


scope(有効範囲)はJavaScriptを含むすべてのプログラミング言語の基本と重要な概念である.スコフに対する理解が欠けていると、他の概念を理解するのは難しい.
関数を例にとります.関数のパラメータは、関数体の内部でのみ参照でき、関数体の外部では参照できません.すなわち,パラメータのスキャンは関数内に限定される.
function add(x, y) {
	console.log(x, y);
  	ruturn x + y;
}

add(2, 5) // => 7
console.log(x, y) // Reference Error
もちろん、変数はコードの一番外側にあってもよいし、コードブロックや関数内に宣言してもよい.コードブロックまたは関数をオーバーラップさせることができます.
var var1 = 1;

if (true) {
	var var2 = 2;
    if (true) {
    	var var3 = 3;
    }
}

function foo() {
	var var4 =4;
    function bar() {
    	var var5 = 5;
    }
}

console.log(var1); // 1
console.log(var2); // 2
console.log(var3); // 3
console.log(var4); // Refernece Errer
console.log(var5); // Refernece Errer
変数は、宣言された位置によって独自の有効範囲を決定します.すなわち、他のコードは変数自体の範囲を参照できます.すべての識別子(変数名、関数名、クラス名など)は、宣言された場所によって、他のコード参照識別子自体の有効範囲を決定します.それをひっくり返す.すなわち,スキャンは指標識別子の有効範囲である.
var x = 'global';

function foo() {
	var x = 'local';
  	console.log(x);
}

foo(); // local

console.log(x); //global
コードの一番外側の領域とfoo関数の内部に同じ名前のxがあることを宣言します.JAvascriptエンジンは、2つの同じ名前の変数のいずれかを参照するかどうかを決定する必要があります.これを識別者決定と呼ぶ.JAvascriptエンジンは、スキャンによってどの変数を参照すべきかを決定します.したがって、ScoFrankはJavaScriptエンジンが識別子を検索する際に使用するルールとも呼ばれます.
コードはどこで実行され、周囲には렉시컬(lexical) 환경と呼ばれるコードがあります.すなわち,コードのコンテキストはディレクトリ環境からなる.これを実現したのは実行コンテキストです.すべてのコードは、実行コンテキストによって評価および実行されます.スキャンは実行コンテキストに関連付けられます.
スコフが異なると,同じ変数名でも異なる処理が発生する.scopeの概念がない場合、同名変数は競合するため、プログラム全体で1つの変数しか使用できません.(const, let)

ひょうほん


変数は、宣言された位置によって有効範囲のスキャンを決定します.すなわち、グローバル宣言の変数はグローバルスキャンを有する変数であり、ゾーン宣言の変数はゾーンスキャンを有する変数である.

グローバルグローバルグローバル


グローバルとは、コードの最も外側の領域を指します.戦区製造전역 스코프.全域に変数を宣言すると、全域スキャンを持つ전역변수になります.グローバル変数はどこでも参照できます.

ローカル


領域とは、関数体の内部を指します.地域スキャンをします.地域に変数を宣言すると,地域スキャンを持つ地域変数となる.領域変数は、宣言された領域とサブ領域(オーバーラップ関数)でのみ参照できます.すなわち,領域変数は自分の領域スキャンとサブ領域スキャンで有効である.

ひょうじチェーン


関数は、グローバルで定義することも、関数ボディの内部で定義することもできます.関数体の内部で定義されている関数を「関数の重ね合わせ」と呼びます.関数体の内部で定義されている関数を「重ね合わせ関数」と呼び、重ね合わせ関数を含む関数を「外部関数」と呼びます.
関数はオーバーラップしてもよく、関数の領域スキャンはオーバーラップしてもよい.これは,スコフが関数の重なりに基づいて階層を持つことを意味する.オーバーラップ関数の領域スキャンとオーバーラップ関数を含む外部関数の領域スキャンには階層があります.このとき外部関数の領域走査を重畳関数の位相走査と呼ぶ.
これにより、すべてのスキャンが1つの階層に接続され、すべての領域の最高スキャンがグローバルスキャンになります.このように、スタンダードが階層的に接続されているのはスタンダードチェーンと呼ばれています.
変数を参照する場合、JavaScriptエンジンは、スキャンチェーンを介して変数を参照するコードのスキャンから上方向に移動し、宣言された変数を参照します.これにより、親鏡で宣言された変数を参照することもできます.

かんすうレベルそうさ


領域とは関数体の内部を指し、領域はスキャンされます.これは、コードブロックではなく関数のみによって領域スキャンが生成されることを意味する.
ほとんどのプログラミング言語は関数体だけでなく、コードブロック(if、for、while、try/catchなど)も領域スキャンを作成します.これらの特性をブロックレベルでスキャンします.ただし、varキーワードとして宣言される変数は、関数のコードブロックのみが地域コードである.これらのプロパティを関数レベルに設定します.
var x = 1;
if (true) {
	var x = 10;
}

console.log(x) // 10
var i = 10;
for (var i = 0; i < 5; i += 1 ){
	console.log(i);
}

console.log(i) // 5
前の2つの場合に示すように、コードブロック内で宣言されたvarはグローバル変数に割り当てられる.varキーワードとして宣言される変数は、関数のコードブロックのみが領域変数とみなされる.ES 6に導入されたlet,constキーワードはブロックレベルスキャンをサポートする.

でんしけんびきょう

var x = 1;
function foo() {
	var x = 10;
  	bar();
}
function bar() {
  console.log(x);
}

foo();
bar();
上記の例の実行結果はbar関数の親スキャンが何であるかによって異なります.
関数の位相は、
  • 関数がどこで呼び出されるかによって決定される.
  • 関数がどこで定義されるかに基づいて、関数の位相を決定する.
  • 関数の位相を第1の方法で決定すると、bar関数の位相はfoo関数の領域とグローバルになる.2つ目の方法で関数の位相スケールを決定すると、bar関数の位相スケールはグローバルスケールになる.
    プログラミング言語は、通常、この2つの方法のうちの1つによって関数の位相走査を決定する.
    1つ目の方法はダイナミックスキャンと呼ばれます.関数を定義するとき、関数がどこから呼び出されるか分かりません.従って、関数が呼び出されたときに位相が動的に決定されるので、動的走査と呼ばれる.
    2つ目の方法はレイクシー・カルスコフ、静的スコフです.動的走査方式のように位相走査は動的変化を維持し,関数定義が評価されると位相走査は静的であるため静的走査と呼ぶ.JavaScriptを含むほとんどのプログラミング言語はLexical Scopeに従います.
    JavaScriptはLexical Scopeに従うため、関数がどこから呼び出されるかではなく、関数がどこで定義されるかに基づいて親Scopeを決定します.関数呼び出しの場所は、親スキャンの決定には影響しません.すなわち,関数の位相スケールは常に自己定義のスケールである.
    この関数の位相走査は,関数定義運転時に静的に決定される.関数定義(宣言、式)を実行して生成された関数オブジェクトは、このように決定された親スキャンを記憶します.関数を呼び出すたびに、関数の親スキャンを参照する必要があるためです.

    整理する

  • オシロスコープの有効識別範囲は
  • である.
  • javascriptエンジンは、スキャンによって参照すべき変数を決定します.したがって、Sco Frank JavaScriptエンジンが識別子を検索する際に使用するルール
  • プローブは、プローブチェーンと呼ばれる層状に接続されている.変数を参照する場合、JavaScriptエンジンは、参照変数のコードのスキャンからスキャンチェーンを介して上方向に移動し、宣言された変数
  • を参照する.
  • javascriptはLexical Scopeに従うので、関数をどこから呼び出すかではなく、関数の定義に基づいて親Scopeを決定します.

    ソース

  • モダンjavascript Deepダイビング