JSは、シングルスレッド実行の順序は間違いである、言語の実行の順序が、JSエンジンがコンパイルされる実装の段落分析によるライン分析と実装プログラムが、段落で行ない、その後のステージは、実施段階です。
例1:可変リフト
foo; // undefined
var foo = function () {
console.log('foo1');
}
foo(); // foo1,foo赋值
var foo = function () {
console.log('foo2');
}
foo(); // foo2,foo重新赋值
例2:機能のアップグレード
foo(); // foo2
function foo() {
console.log('foo1');
}
foo(); // foo2
function foo() {
console.log('foo2');
}
foo(); // foo2
例3:文の優先機能>変数
foo(); // foo2
var foo = function() {
console.log('foo1');
}
foo(); // foo1,foo重新赋值
function foo() {
console.log('foo2');
}
foo(); // foo1
上記3つの実施例では、最初の例では、可変リフトされ、第二の例では、第三の実施例の機能を強化するために変数宣言より、関数宣言高い優先度です。
なお、同じスコープ内で同じ名前の存在下での関数宣言は、それは前の関数宣言バックを交換すること。
実行コンテキスト
実行コンテキストの3つのタイプがあります。
- グローバル実行コンテキスト:唯一のグローバルオブジェクトブラウザがあり、ウィンドウオブジェクトである
this
グローバルオブジェクトをポイントします。 - 関数の実行コンテキスト:多数の存在は、唯一の関数が呼び出されたときに作成される、関数を呼び出すたびに新しい実行コンテキストを作成します。
- 評価関数実行コンテキストは:での動作を意味し
eval
、関数のコードめったに使用し、推奨されません。
実行コンテキストスタック
JSエンジンは実行コンテキストの多くを作成するので、そのJSエンジンは、実行コンテキストの作成スタックする(実行コンテキストスタック、ECS)を管理、実行コンテキストを。
JavaScriptの初期化時には、実行コンテキストにプッシュされます場合はスタックグローバル実行コンテキストを、我々はglobalContextでそれを表現し、場合にのみ、アプリケーション全体の終了時間、実行スタックになります空なので、プログラムの終了前に、実行は永遠に下を積み重ねますそこglobalContext。
ECStack = [ // 使用数组模拟栈
globalContext
];
違いを見つけます
次の2つのコード部分は、実行結果は同じですが、違いはどのようなコードの2枚のですか?
//代码一
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
//代码二
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
答えは同じではありませんスタック実行コンテキストを変更することです。
コードの最初の部分:
ECStack.push(<checkscope> functionContext);
ECStack.push(<f> functionContext);//这里checkscope函数还没出栈,且函数f入栈
ECStack.pop();
ECStack.pop();
コードの2番目の段落:
ECStack.push(<checkscope> functionContext);
ECStack.pop();//这里checkscope函数已经执行结束,出栈
ECStack.push(<f> functionContext);
ECStack.pop();
関数コンテキスト
アクティブオブジェクト(起動オブジェクト、AO)との関数のコンテキスト内で可変オブジェクトを表します。
活動との変数オブジェクトの違いという
- 図1は、可変オブジェクト(VO)が仕様やJSエンジンが達成され、直接JS環境にアクセスすることができません。
- 2ときに、入射される可変オブジェクトに実行コンテキストを活性化する、いわゆるアクティブオブジェクト(AO)の活動この時オブジェクト上の種々の特性にアクセスします。
関数が呼び出されると、それが作成されます引数オブジェクトを、そして自動的にローカル変数の初期化引数を、引数オブジェクトを参照してください。配列要素の値として渡されたパラメータはすべての引数のオブジェクトになります。
実装プロセス
処理のためのコードの実行コンテキストは、2つのフェーズに分割されます
- 1、に実行コンテキスト
- 図2に示すように、コード実行
実行コンテキストに
明らかに、この時間は、コードを実行しません
このとき、(順序次の初期化)変数を含むオブジェクト:
- 1の機能全てのパラメータ(機能のみコンテキスト):undefinedにない引数は、属性値が設定されています。
- 図2に示すように、関数宣言:同じ名前の変数オブジェクトのプロパティが既に存在する場合、完全に交換性を。
- 図3は、変数宣言:変数名場合パラメータまたは機能を有するが同じに宣言された場合、変数宣言は干渉しない既に存在するそのような属性。
例を見てください:
function foo(a) {
var b = 2;
function c() {}
var d = function() {};
b = 3;
}
foo(1);
上記のコードでは、この時間はAOであります
AO = {
arguments: {
0: 1,
length: 1
},
a: 1,
b: undefined,
c: reference to function c(){},
d: undefined
}
パラメータの引数今回は、すでに割り当てていますが、変数が定義されていますが、初期値
コードの実行
この段階は、順次ますコードを実行し、それが実行された後、AOは、以下、オブジェクトの内容を変更し、:
AO = {
arguments: {
0: 1,
length: 1
},
a: 1,
b: 3,
c: reference to function c(){},
d: reference to FunctionExpression "d"
}
ここでは、変数が割り当てられます。
次のように要約:
- 1、グローバルコンテキスト変数オブジェクトは、グローバルオブジェクトを初期化されています
- 図2に示すように、コンテキストオブジェクト初期化変数の関数は、引数オブジェクト含みます
- 3、あろうオブジェクト変数の実行コンテキストを入力するとき、パラメータ、関数宣言を追加し、変数宣言初期プロパティ値、等
図4は、コードを実行し、それが再び変数オブジェクトのプロパティの値を変更します
参考記事