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

所以就算window.eval(s)不一样。eval(s)window.eval === eval

附言

请注意,eval发生这种情况有一个特殊的特定语言规则,但在其他情况下,出于不同的原因,也可以观察到同样明显奇怪的行为。

如果您有一个x定义了方法的对象,m那么

x.m()

不一样

var mm = x.m; mm();

因为this在第一种情况下将x在代码执行期间绑定到,m而在第二种情况下this将是全局对象。

所以在这种情况下x.m()也不同于mm()即使x.m === mm

同理x.m()不一样是[x.m][0]()因为在后者中this会在方法代码执行期间绑定到数组对象而不是绑定到x.

于 2013-10-25T07:13:37.613 回答