编辑:Bergi指出我原来的答案是错的,他是对的。由于eval
在其自己的作用域中运行,并且功能构造函数仍然按照spec在功能范围内运行,所以这两个都不可行。
虽然我自己使用vm
模块多次使用node.js完成了这类事情,您可以对代码的执行位置进行更细致的控制,但似乎浏览器需要不同的方法。
以这种方式共享变量的唯一方法是在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然后.call
荷兰国际集团它
在你的情况,这将是这样的:
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函数,那么 Init如10.4.1.1所述,使用eval代码作为C来对执行上下文进行ialize,就好像它是一个全局执行上下文一样。
如果此代码在node.js中运行,请考虑使用vm模块。还要注意,这种方法仍然不安全,它将允许您运行代码来更改代码。
为什么你会这样做呢? – epascarello 2013-03-14 12:49:37
@epascarello阅读代码,他正在制作一个脚本跑步者... – 2013-03-14 12:49:50
@BenjaminGruenbaum,我知道,我想知道*为什么*,而不是它做什么。 – epascarello 2013-03-14 13:00:36