编辑: Bergi指出我原来的答案是错误的,他是正确的。由于eval
在其自己的范围内运行,并且函数构造函数仍然根据规范在函数范围内运行,这两者都不可能。
虽然我自己用 node.js 做了几次这样的事情,使用的vm
模块可以让你更精细地控制代码的执行位置,但似乎浏览器需要不同的方法。
以这种方式共享变量的唯一方法是在 JavaScript 执行的全局范围内(可能在 iframe 中)这样做。你可以做到这一点的一种方法是脚本标签注入。
function run(code){
var sc = document.createElement("script");
sc.setAttribute("type","text/javascript");
sc.innerHTML = code;
document.body.appendChild(sc);
}
run("var x = 5");
run("document.write(x)");
(这里是这个代码在行动)
至于范围包装器,而不是将它们注入到同一帧中,而是将它们注入另一个iframe
. 这会将他们的窗口对象范围限定为该 iframe,并允许您共享上下文。
我为我之前的回答谦虚地道歉,我误读了规范。我希望这个答案对你有所帮助。
我将之前的答案留在这里,因为我仍然相信它提供了一些关于构造函数如何工作eval
的见解Function
。
在非严格模式下运行代码时,eval
在页面的当前上下文中运行函数声明完成后,它声明的范围会消失,函数也会随之消失。
考虑使用Function 构造函数,然后.call
ing 它
在你的情况下,这将是这样的:
var scopeWrapper = {};
scopeWrapper.run = function(code){
var functionToRun = new Function(code);
functionToRun.call(scopeWrapper);
}
scopeWrapper.run('this.test = function() { alert("passed"); }');
scopeWrapper.run("this.test()")
这是直接来自规范的参考:
如果没有调用上下文或者如果 eval 代码没有通过对 eval 函数的直接调用 (15.1.2.1.1) 进行评估,则初始化执行上下文,就好像它是使用 eval 代码作为 C 的全局执行上下文一样如 10.4.1.1 中所述。
如果此代码在 node.js 中运行,请考虑使用vm模块。另请注意,这种方法仍然不安全,因为它允许您运行的代码更改您的代码。