编辑: Bergi 指出我原来的答案是错误的,他是正确的。由于eval 在其自己的范围内运行,并且根据spec,函数构造函数仍然在函数范围内运行,因此两者都不可能。
虽然我自己在 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)");
(here is this code in action)
至于作用域包装器,不是在同一帧中注入它们,而是在另一个iframe 中注入它们。这会将他们的窗口对象限定为该 iframe,并允许您共享上下文。
我为我之前的回答谦虚地道歉,我误读了规范。希望这个回答对你有帮助。
我将之前的答案留在这里,因为我仍然相信它提供了一些关于 eval 和 Function 构造函数如何工作的见解。
在非严格模式下运行代码时,eval 在您页面的当前上下文中运行
在你的函数声明完成后,它声明的范围就消失了,函数也随之消失。
考虑使用Function constructor,然后.calling它
在你的情况下是这样的:
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()")
这里直接引用from the spec:
如果没有调用上下文或者 eval 代码不是通过直接调用 (15.1.2.1.1) 来评估 eval 函数,那么,
如 10.4.1.1 中所述,使用 C 的 eval 代码将执行上下文初始化为全局执行上下文。
如果此代码在 node.js 中运行,请考虑使用 vm 模块。另请注意,这种方法仍然不安全,因为它允许您运行的代码更改您的代码。