如何在一个作用域中执行JS代码的不同部分
How to execute different partsof the JS code in one scope
我有几个脚本块相互依赖。我需要在一个作用域中执行它们。
我的尝试:
var scopeWrapper = {};
with(scopeWrapper) {
(function() {
this.run = function(code) {
eval(code);
};
}).call(scopeWrapper);
}
scopeWrapper.run('function test() { alert("passed"); }');
scopeWrapper.run('test();');
我得到'test is not defined'错误。看起来代码是在不同的作用域中执行的。为什么会发生这种情况?
编辑: 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
它
在你的例子中,应该是这样的:
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)求值,那么,如10.4.1.1所述,使用C语言的eval代码初始化执行上下文,就像它是一个全局执行上下文一样。
如果这段代码在node.js中运行,考虑使用vm模块。还要注意,这种方法仍然不安全,因为它允许您运行的代码更改您的代码。
test
只存在于this.run
的作用域中,并且只在调用时存在:
// global scope
(function(){
// local scope (equivalent of your "run" function scope)
eval('function f(){};');
console.log(f); // prints "function f(){}"
})();
console.log(f); // prints "ReferenceError: f is not defined"
每次调用run
都会创建一个新的作用域,其中每个code
都被单独求值。
- Meteor JS中代码的重复使用部分
- 骨干模型默认值-todos.js示例中不必要的代码
- 为什么indexOf在这个js代码中不起作用
- 点击facebook像素跟踪注册(JS/JQUERY代码)
- js代码从jQuery转换为原生代码
- JS代码中的减号
- 将JS函数传递给Emscripten生成的代码
- 谷歌地图Api和JS代码不工作
- HTML 5 和 3.js 代码不会在网页上显示任何内容
- Node.js:异步代码 + js 闭包的问题
- Chrome 开发者工具 - 控制台.log原生代码 JS
- 为jQuery和KNOCKOUT通用化javascript代码.js成为一个可重用的模块
- .ninnerHtml代码(JS/JQuery)无法识别html表中的动态内容
- 生成唯一的6位代码js
- 我得到了“;赋值中的左侧无效“;在我的代码(JS)中
- 更改代码(JS)中JQuery Mobile Calendar日期的状态
- 如何改进代码JS(Jquery)?一个简单的下拉列表
- 从传输中了解代码.js
- 这段代码(JS)的区别是什么?
- JavaScript倒计时计时器代码[JS]