这有效:
var i = 'foo';
eval('function '+i+'(param) { this.param = param; return this; }');
console.log(foo); // [Function: foo]
这不是:
['bar', 'quux'].forEach(function(i) {
eval('function '+i+'(param) { this.param = param; return this; }');
});
console.log(bar); // ReferenceError: bar is not defined
显然,forEach
函数或其从属范围会混淆事物。我检查过bar
函数是否可用,但它不能在外面存活。
答案 0 :(得分:3)
forEach
回调会创建一个闭包。封闭中定义的任何东西都是世界上最接近的。您可以将代码的最终结果映射为等效于此:
function() {
function bar() { ... }
function quux() { ... }
}
// bar and quux are out of scope here :(
如果您希望将这些功能提供给全世界,您将需要一些对象来附加这些功能。 window
是最便宜的,或类似的东西更好一点:
var myScope = {};
['bar', 'quux'].forEach(function(i) {
eval('myScope["'+i+'"] = function(param) { this.param = param; return this; }');
});
myScope.bar(); // woo hoo!
答案 1 :(得分:1)
['bar', 'quux'].forEach(function(i) {
this.eval('function '+i+'(param) { this.param = param; return this; }');
});
['bar', 'quux'].forEach(function(i) {
window.eval('function '+i+'(param) { this.param = param; return this; }');
});
['bar', 'quux'].forEach(function(i) {
eval.call(null, 'function ' + i + '(param) { this.param = param; return this; }');
// same
// eval.call(window, 'function ' + i + '(param) { this.param = param; return this; }');
});
答案 2 :(得分:1)
forEach
的问题是eval
在匿名函数内运行,因此创建的变量将被限制在该范围内,无法从外部访问。
要修复它,只需以不需要包装功能的其他方式迭代您的数组。例如:
for
循环:
var names = ['bar', 'quux'];
for(var i=0; i<names.length; ++i)
eval('function '+names[i]+'(param) { this.param = param; return this; }');
for...of
(ECMAScript 6)
for(var i of ['bar', 'quux'])
eval('function '+i+'(param) { this.param = param; return this; }');
请注意,这不会在严格模式下工作:
10.4.2.1严格模式限制
eval代码无法实例化变量或函数绑定 调用eval if的调用上下文的变量环境 调用上下文的代码或eval代码是strict code。相反,这样的绑定在新的实例化中 VariableEnvironment只能通过评估代码访问。
答案 3 :(得分:0)
您可以简单地将功能分配给全局对象:
['bar', 'quux'].forEach(function(i) {
eval('window.' + i + ' = function(param) { this.param = param; return this; }');
});
答案 4 :(得分:0)
还有一个答案!使用window
对象:
['bar', 'quux'].forEach(function(i) {
eval('window.'+i+' = function(param) { this.param = param; return this; }');
});