1

次の 2 つの小さなスクリプトがあります。

スクリプト 1:

eval("local = 3;");
console.log(typeof local);
Function("console.log(typeof local);")();

出力:

number
number

スクリプト 2:

eval("var local = 3;");
console.log(typeof local);
Function("console.log(typeof local);")();

出力:

number
undefined

何を与える?var local = 3渡された文字列に aまたは aが含まれているかどうかに関係なく、eval は local をグローバル名前空間に配置する必要がありlocal = 3ます。Function(...)その場合、2 番目のケースでは local の型が number であり、未定義ではないことがわかりませんか?

編集1:

JSFiddle で両方のスクリプトを実行した結果が得られました。ただし、JSFiddle の外部でそれらを実行すると、両方の出力が次の場所で期待される結果が得られます。

number 
number
4

1 に答える 1

2

MDNから:

コンストラクターで作成された関数はFunction、作成コンテキストへのクロージャーを作成しません。それらは常にウィンドウ コンテキストで実行されます (ただし、関数本体が "use strict"; ステートメントで始まる場合を除きます。この場合、コンテキストは未定義です)。

仕様に関しては、これは15.3.2.1のステップ 11 によるものです(強調は鉱山):

FormalParameterListopt として P を、FunctionBody として body を渡して、13.2 で指定されているように作成された新しい Function オブジェクトを返します。Global Environment を Scope パラメーターとして渡し、 strict を Strict フラグとして渡します。

したがって、スクリプト 2 はローカル スコープに変数を作成し (これは global ではない、または出力が異なると想定しています1 )、console.logeval'd byFunctionはそれを見ることができません。


1コメントが確認したように、jsfiddle でテストを実行していました。これは、デフォルトでコードを window.onload ハンドラーにラップし、グローバル スコープから強制的に除外します。

于 2013-08-02T19:52:38.967 に答える