変数宣言ごとに(初期化ではありません!)。次のことが起こります (セクション#10.5
):
8.コード内のVariableDeclarationおよびVariableDeclarationNoIn dごとに、ソース テキストの順に実行します。
- dnをdの識別子とします。
- varAlreadyDeclaredを、引数としてdnを渡してenv のHasBinding具象メソッドを呼び出した結果とします。
- varAlreadyDeclaredがfalseの場合、
- env のCreateMutableBinding 具象メソッドを呼び出し、 dnとconfigurableBindingsを引数として渡します。
- 引数としてdn、undefined、およびstrictを渡して、 env のSetMutableBinding 具象メソッドを呼び出します。
ご覧のとおり、 が検出されるたびvar x
に、名前を持つ変数がx
環境に既に存在するかどうかがテストされます。はいの場合は単に無視されますが、そうでない場合は変数が宣言され、 で初期化されundefined
ます。
コードはグローバル スコープで実行されるため、グローバル スコープにJSON
存在するかどうかをテストします。したがって、JSON
すでに存在する場合var JSON;
は無視されます。
この動作のテスト/説明に関するいくつかの考え:
JavaScript 実行のどの時点でグローバル オブジェクトが作成されるかはわかりませんが、他のすべてのスクリプトが評価される前に作成されると思います。つまり、変数宣言の前JSON
に存在し、値を持っています。これは、2 つのスクリプトを含める場合にのみシミュレートできるものです (インラインにすることもできます。それらは次々に評価されます)。
試す:
// script1.js
var foo = 'bar';
// script2.js
var foo;
if(!foo) {
foo = 'baz';
}
alert(foo);
// include script2.js after script1.js
結果は?(詐欺師はここを見てください)。
単一のスクリプト ファイルにいるときはいつでも、すべての変数宣言が先頭に持ち上げられます。だからあなたが持っているなら
var foo = 'bar';
var foo;
if(!foo) {
foo = 'baz';
}
スクリプトは実際には次のように実行されます。
var foo;
var foo;
foo = 'bar';
if(!foo) {
foo = 'baz';
}
var foo;
この時点ではまだ値がないため、2 番目が最初のものを上書きするかどうかを実際にテストすることはできません。したがって、これは上記の動作を示す良い例ではありません。