具有回报值的全球评估?

时间:2013-10-25 07:08:52

标签: javascript eval

经过一段时间的搜索,我希望找到一个带有返回值的全局评估解决方案。

  • eval将在当前范围内运行
  • Function constructor将在其自己的本地范围内执行,并可访问全局范围
  • setTimeout技巧是异步操作
  • script injection无法返回值
  • window.execScript也 - 无法返回值

所以我的问题是:

是否还有其他技术可以在全球范围内运行并且可以返回值?

(示例将非常感谢)。

1 个答案:

答案 0 :(得分: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也不一样。

PS

请注意eval有一个特殊的特定语言规则可以实现,但在其他情况下也会出现同样明显奇怪的行为,原因不同。

如果您的对象x的方法已定义为m,那么

x.m()

不同
var mm = x.m; mm();

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

因此,在这种情况下,即使x.m()mm()也不同于x.m === mm

出于同样的原因,x.m()[x.m][0]()不同,因为后者this将在执行方法代码时绑定到数组对象,而不是绑定到{ {1}}。