我有几个相互依赖的脚本块.我需要在一个范围内执行它们.
我的尝试:
var scopeWrapper = {};
with(scopeWrapper) {
(function() {
this.run = function(code) {
eval(code);
};
}).call(scopeWrapper);
}
scopeWrapper.run('function test() { alert("passed"); }');
scopeWrapper.run('test();');
Run Code Online (Sandbox Code Playgroud)
我得到'测试未定义'错误.似乎代码在不同的范围内执行.为什么会这样?
编辑: 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)");
Run Code Online (Sandbox Code Playgroud)
(这是代码在行动)
对于范围包装器,不是将它们注入同一帧中而是将它们注入另一个iframe.这会将他们的窗口对象范围限定为iframe,并允许您共享上下文.
我谦卑地为我之前的回答道歉,我误读了规范.我希望这个答案可以帮到你.
我在这里留下我之前的答案,因为我仍然认为它提供了一些有关如何eval和Function构造函数工作的见解.
在非严格模式下运行代码时,在eval页面的当前上下文中运行完成函数声明之后,声明它的作用域,以及函数.
考虑使用Function构造函数然后使用.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()")
Run Code Online (Sandbox Code Playgroud)
如果没有调用上下文或者eval代码没有通过eval函数的直接调用(15.1.2.1.1)进行评估,则将执行上下文初始化为使用eval代码作为C的全局执行上下文如10.4.1.1中所述.
如果在node.js中运行此代码,请考虑使用vm模块.另请注意,这种方法在允许您运行的代码更改代码的方式上仍然不安全.
| 归档时间: |
|
| 查看次数: |
219 次 |
| 最近记录: |