3

.apply と .call の最初の引数が「this」オブジェクトであることを MDN ドキュメントから読みましたが、

var stringToEval = "console.log(this)";
eval.call(null, stringToEval);
eval.apply(null, [stringToEval]);

上記の両方の行のコードでは、(ブラウザーで) Window オブジェクトをログに記録します。両方のメソッドで最初の引数として渡したのは、null をログに記録するべきではありませんか?

4

2 に答える 2

2

MDNから:

これの価値は楽しみへの呼びかけに提供されました。これは、メソッドによって表示される実際の値ではない可能性があることに注意してください。メソッドが非厳密モード コードの関数である場合、null および undefined はグローバル オブジェクトに置き換えられ、プリミティブ値はボックス化されます。

グローバル オブジェクトは window です。

null、未定義、または eval を持つオブジェクトを渡すかどうかは問題ではないため、編集してください。内部evalは、eval 呼び出しの直前thisと同じになります。this

ECMA-262 5.1 のセクション 15.1.2.1 に従って、eval は文字列を受け取り、それを ECMAscript として解析します。有効な ECMAscript である場合は、呼び出し元のコンテキストで実行されます。したがって、あなたの場合、 eval への呼び出しはconsole.log(this)、実行時に自分自身を置き換えるかのように考えることができます。その置換により、プログラムは次のようになります。

var stringToEval = "console.log(this)";
console.log(this);
console.log(this);

これにより、DOMWindowオブジェクトを 2 回出力する理由が明確になります。次のように回避できます。

var stringToEval = "console.log(this)";
(function(str){ eval(str); }).call({not: "empty"}, stringToEval);
(function(str){ eval(str); }).apply({not: "empty"}, [stringToEval]);

eval がそれ自体を置き換えると、渡されたオブジェクトを参照するconsole.log(this)無名関数のコンテキストになります。this

この JSFiddle を参照してください

于 2012-06-07T05:28:01.353 に答える
0

eval明示的にに設定thisして呼び出すと、これは評価されたコード内のオブジェクトとnullは何の関係もありません。呼び出したものと同じに設定されたコードを評価するということはどこにもありません。実際、そうすることは間接的に呼び出しており、最新のブラウザーのグローバルコンテキストでevalコードが実行される結果になります。thisevalthisthisevaleval

したがって、通常の機能でテストする必要があります。

function test() {
    console.log(this);
}

test.call({});
test.apply({});
于 2012-06-07T05:51:25.600 に答える