JavaScriptはコンテキスト変数オブジェクトおよび変数、関数宣言を実行しますが、なぜ事前に
12187 ワード
前のブログでは、「JavaScriptの演算、バイナリ浮動小数点の丸め誤差と比較、類型転換と変数宣言の早期問題について」に言及しましたが、関数、変数声明は前倒ししていますが、なぜ説明されていませんでしたか?本文では、コンテキストと変数オブジェクトの両方の観点から、なぜ関数、変数の申明が事前に行われるのかを話します.
_; は実行文脈と変数対象について、個人的にはオンラインでいくつかの優れた博文があると思います._; 1)はJavaScriptシリーズを深く理解します.(11):実行文脈(Execution Cotexts)は、JavaScriptシリーズを深く理解します.専門用語を比較して理解しやすいです.前の段階(二):文脈の詳細な図解を実行し、前の段階(三):変数の対象の詳細は、個人的にはよく書けていると思います.読者の友達は、実行コンテキストと変数のオブジェクトを深く理解したいなら、この2つのブログを読んでください.
1、実行コンテキスト
コントローラがECMAScript実行可能なコードに移るたびに、実行コンテキストに入ります.実行コンテキストは現在のコードの実行環境として理解できます.JavaScript実行環境は大体3つの状況を含みます.グローバル環境:JavaScriptコードが実行されると、まずこの環境に入ります.例えば、外部のjsファイルまたはラベル内のコードをロードします. 関数環境:関数を呼び出して実行すると、現在の関数でコードが実行されます. eval(使用を推奨せず、無視できる) したがって、JavaScriptコードの実行中に、必ず複数の実行コンテキストが発生します.JavaScriptエンジンはスタックの方式でそれらを処理します.ECStock=[]で表してもいいです.まずグローバルコンテキストに押し入れられます.関数のコンテキストを終了して、スタックの一番上のECStockからポップアップし、ページまたはブラウザが閉じるまでグローバルコンテキストは常に存在します.
2、変数オブジェクト
実行コンテキストにはライフサイクルがあります.作成段階とコード実行段階です.作成段階:この段階では、実行文脈はそれぞれ変数オブジェクトを作成し、スコープチェーンを確立し、thisの指向を決定します.変数オブジェクトはVOで表されると、VO={argments、function、var変数}に類似するべきです. コードの実行フェーズ:作成が完了すると、コードの実行が開始されます.このとき、変数の割り当て、関数の参照、その他のコードの実行が完了します. DEMOを見てください関数のすべてのモダリティ(関数実行コンテキストの場合)、argments すべての関数宣言 すべての変数宣言 3、関数宣言の優先度が変数宣言より高い
同様に事前に宣言されていますが、関数宣言の優先度は変数宣言より高く、関数宣言が先に実行されます.変数名(同名関数が既に宣言されている)が上書きされない場合、変数は先に定義されていますが、その後の割当値は関数宣言を上書きします.古典的なデモを見てください.
_; は実行文脈と変数対象について、個人的にはオンラインでいくつかの優れた博文があると思います._; 1)はJavaScriptシリーズを深く理解します.(11):実行文脈(Execution Cotexts)は、JavaScriptシリーズを深く理解します.専門用語を比較して理解しやすいです.前の段階(二):文脈の詳細な図解を実行し、前の段階(三):変数の対象の詳細は、個人的にはよく書けていると思います.読者の友達は、実行コンテキストと変数のオブジェクトを深く理解したいなら、この2つのブログを読んでください.
1、実行コンテキスト
コントローラがECMAScript実行可能なコードに移るたびに、実行コンテキストに入ります.実行コンテキストは現在のコードの実行環境として理解できます.JavaScript実行環境は大体3つの状況を含みます.
2、変数オブジェクト
実行コンテキストにはライフサイクルがあります.作成段階とコード実行段階です.
function test() {
console.log(a);
console.log(foo());
var a = 1;
function foo() {
return 2;
}
}
test();
コードがtest()に実行されるたびに、新しい関数を作成してコンテキストを実行し、ECStock[globalEC,testEC]に押し込んで、testECは2つの段階があり、疑似コードは以下の通りである.//
testEC = {
VO: {}, //
scopeChain: {},
this
}
VO = {
arguments: {...},
foo: <foo reference> // foo
a: undefined
}
//
VO -> AO // VO , AO ,Active Object
AO['a'] = 1
```js
demo , :
```js
function test() {
function foo() { //
return 2;
}
var a;
console.log(a);
console.log(foo());
a = 1;
}
test();
ここで、なぜ変数、関数宣言が前倒しされたのかが分かりました.まとめてみます.2つの文があります.1)実行文脈は2つの段階があり、作成段階(コンテキストに入る)、実行段階があります.2)作成段階では変数オブジェクトが作成されます.変数オブジェクトには以下の属性が含まれます.同様に事前に宣言されていますが、関数宣言の優先度は変数宣言より高く、関数宣言が先に実行されます.変数名(同名関数が既に宣言されている)が上書きされない場合、変数は先に定義されていますが、その後の割当値は関数宣言を上書きします.古典的なデモを見てください.
alert(x); // function x() {}
var x = 10;
alert(x); // 10
x = 20;
function x() {};
alert(x); // 20
コンテキスト、変数オブジェクトを結合すると、コードは同じです. function x() {};
alert(x); // function x() {}
x = 10;
alert(x); // 10
x = 20;
alert(x); // 20
関数宣言ではなく、関数表現ですか? console.log(x); // undefined
var x = 10;
console.log(x); // 10
x = 20;
var x = function() {};
console.log(x); // function x() {}
関数式、変数定義と同等で、コードの順序によって実行されます.上記のコードは同じです. var x;
console.log(x); // undefined
x = 10;
console.log(x); // 10
x = 20;
x = function() {};
console.log(x); // function x() {}