经过一段时间的搜索,我希望找到一个带有返回值的全局评估解决方案。
eval
将在当前范围内运行Function constructor
将在其自己的本地范围内执行,并可访问全局范围setTimeout
技巧是异步操作script injection
无法返回值window.execScript
也 - 无法返回值所以我的问题是:
是否还有其他技术可以在全球范围内运行并且可以返回值?
(示例将非常感谢)。
答案 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
也不一样。
请注意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}}。