Javascriptの変数定義と簡単な演算実験を通してJS内部の運行メカニズムを見ます.
2414 ワード
非常に古典的ないくつかの面接問題:
一対三の類推では、「a」「in topまたは」a「in selfは、結局windowと同じです.上訴運行環境の中で、topはwindowです.selfは基本的にwindowと交換できます.これは理解できますよね.あとはa in documentを試してみます.皆さんは分かります.documentはaとwindowの属性に属しています.
次の問題を続けます.
事前コンパイルの間、JS解釈器には変数宣言と関数宣言のリフティング機構があります.(variable declaration hoisting and function declaration hoisting)は、変数実行のcontextにアップグレードし、undefinedを割り当てます.具体的な内部操作の経過:まず、現在実行されている環境下の活動対象を作成します.を選択して、 var宣言の変数は、活動対象の属性(すなわち、活動対象に追加)として設定され、その割当値はundefinedとなり、その後、function定義の関数も活動対象に追加されます.を選択します.ステートメントを実行する間、解釈器は変数の割り当てを初期化し、関数名変数を関数体に向けることができます.要約すると、関数宣言はプリコンパイルの間に静的に作成され、関数式は実行中に動的にビルドされます.
山のように説明し、元の話題に戻ると、解釈器のプリコンパイルを経て、aは関数として宣言されますが(function a(x){x&a(--x);})、実行中にaは1に初期化されますので、結果はまだ1です.
また、javascriptインタプリタはブロックごとにプリコンパイルされ、すなわち「script」タブでブロックを分けることに注意が必要です.
if(!("a" in window)){
var a = true;
}
alert(a);
以上のテーマの実行結果は「indefined」です.aを「aとして見たほうが分かりやすいですよね.変数aはグローバルスコープで定義されていますが、グローバルスコープ変数はすべてwindowオブジェクトの属性ですので、a in windowは自然にtrueです.残りは説明しなくてもいいですよね.また、グローバル変数オブジェクトの声明:VO(global){a:undefined.一対三の類推では、「a」「in topまたは」a「in selfは、結局windowと同じです.上訴運行環境の中で、topはwindowです.selfは基本的にwindowと交換できます.これは理解できますよね.あとはa in documentを試してみます.皆さんは分かります.documentはaとwindowの属性に属しています.
次の問題を続けます.
var a = 1;
var b = function a(x){
x && a(--x);
};
alert(a);
実行の結果は「1」です.この問題は関数式と関数声明の深い違いをテストしています.テーマは関数式で、後は関数名を使っています.ここの関数名の作用領域は形参に相当します.つまり外部の作用領域に影響がないので、大域作用域のaと声明が衝突することはありません.var a = 1;
function a(x){
x && a(--x);
}
alert(a);
関数表現を関数宣言function a(x){x&a(--x)}に置き換えると、非常に興味深い現象が発生します.ここで栄養剤を補充すると、栄養不良になります.Javascriptはコンパイルする必要がなく、説明スクリプト言語です.(JSエンジンは必ずしも単一の解釈器ではなく、googleのV 8などです.)が、インタプリタにあります.解釈の過程では、Javascriptプリコンパイルとステートメントに分けて2つの段階を実行しますが、変数オブジェクト宣言と関数宣言はプリコンパイルの間に処理されます.値付けと変数初期化は実行中に処理されます.事前コンパイルの間、JS解釈器には変数宣言と関数宣言のリフティング機構があります.(variable declaration hoisting and function declaration hoisting)は、変数実行のcontextにアップグレードし、undefinedを割り当てます.具体的な内部操作の経過:まず、現在実行されている環境下の活動対象を作成します.を選択して、 var宣言の変数は、活動対象の属性(すなわち、活動対象に追加)として設定され、その割当値はundefinedとなり、その後、function定義の関数も活動対象に追加されます.を選択します.ステートメントを実行する間、解釈器は変数の割り当てを初期化し、関数名変数を関数体に向けることができます.要約すると、関数宣言はプリコンパイルの間に静的に作成され、関数式は実行中に動的にビルドされます.
山のように説明し、元の話題に戻ると、解釈器のプリコンパイルを経て、aは関数として宣言されますが(function a(x){x&a(--x);})、実行中にaは1に初期化されますので、結果はまだ1です.
また、javascriptインタプリタはブロックごとにプリコンパイルされ、すなわち「script」タブでブロックを分けることに注意が必要です.