5

しばらく検索した後、戻り値を持つグローバル eval の解決策を見つけたいと思っていました。

  • eval現在のスコープで実行されます
  • Function constructorグローバルスコープにアクセスできる独自のローカルスコープで実行されます
  • setTimeoutトリックは非同期操作です
  • script injection値を返すことはできません
  • window.execScriptまた、値を返すことはできません

だから私の質問は:

グローバルスコープで実行され、値を返すことができる他の手法はありますか?

(例は非常に高く評価されます)。

4

1 に答える 1

4

代わりに、eval をグローバル スコープで実行することができます。

eval(s)

ただ使う

window.eval(s);

また

var e=eval; e(s);

また

[eval][0](s)

これは驚くべきことに、Javascript が奇妙で、文字列を評価するためevalに元のオブジェクトを直接使用している場合、現在のコンテキストで評価が行われるという特別な規則があるためです。eval

代わりに「間接評価」が使用される場合 (つまり、変数に格納evalしてから変数を使用する場合、またはオブジェクトevalを使用してアクセスする場合でもwindow)、評価はグローバル コンテキストで行われます。

これは Javascript コンソールで確認できます。

function foo() {
    eval("function square(x){ return x*x; }");
}

function bar() {
    window.eval("function square(x){ return x*x; }");
}

foo()

square(12) // <-- this gives an error; direct evaluation was used

bar()

square(12) // <-- this returns 144

Soはifwindow.eval(s)と同じではありません。eval(s)window.eval === eval

PS

evalこれが発生するための特別な特定の言語ルールがあることに注意してください。

xメソッドが定義されたオブジェクトがあるm場合

x.m()

と同じではありません

var mm = x.m; mm();

最初のケースではコードの実行中thisにバインドされ、2 番目のケースではグローバル オブジェクトになるためです。xmthis

なのでこの場合も ifx.m()とは違います。mm()x.m === mm

同じ理由で、は と同じx.m()ではありません[x.m][0]()。後者でthisは、メソッド コードの実行中に にバインドされるのではなく、配列オブジェクトにバインドされるからxです。

于 2013-10-25T07:13:37.613 に答える