给定此函数调用:
var funcs = obj.getClosures([2, 4, 6, 8], function(x) {
return x*x;
});
我有以下功能:
getClosures : function(arr, fn) {
var funcs = [];
var array = arr;
var i = 0;
var l = array.length;
(function(i, array) {
for (; i < l; i++) {
funcs[i] = function(i, array) {
return fn(array[i]);
};
}
}(i, array));
return funcs;
},
我希望能够遍历返回的数组并获得数组中每个项目的平方根值,如下所示:
for (var i = 0; i < arr.length; i++) {
funcs[i]();
}
每次循环结果:4,16,36,64
我的funcs数组不应该在每个索引中都有一个函数引用,可以使用相关的参数值轻松调用吗?我哪里出错了?
答案 0 :(得分:2)
有多个“问题”:
IIFE (function(i, array) { ... }(i, array));
在这里完全没有任何好处。如果删除它,代码将具有完全相同的行为。如果要捕获i
和array
的当前值,则必须将移动到 for
循环中。
您的功能定义不正确。
funcs[i] = function(i, array) {
return fn(array[i]);
};
在函数内部,array[i]
将引用传递给函数的参数。如果你没有通过,它们将是undefined
,代码将抛出错误。也就是说,根据该定义,您必须执行如下函数:
for (var i = 0; i < arr.length; i++) {
funcs[i](i, array);
}
首先打败了产生这些功能的目的。
如果要创建一个可以访问定义函数范围的i
和array
的闭包,请不要定义具有相同名称的参数。
可能的解决方案:
for (var i = 0, l = array.length; i < l; i++) {
(function(i) {
funcs[i] = function() {
return fn(array[i]);
};
}(i));
}
或者更简单,如果您的代码在支持.map
的环境中运行:
getClosures: function(arr, fn) {
return arr.map(function(v) {
return function() {
fn(v);
};
});
},
相关问题:
答案 1 :(得分:0)
var obj = {
getClosures : function(arr, fn) {
var funcs = [];
var array = arr;
var i = 0;
var l = array.length;
(function(i, array) {
for (; i < l; i++) {
funcs[i] = function(i, array) {
return fn(array[i]);
}.bind(this,i,array);
}
}(i, array));
return funcs;
}
}
var funcs = obj.getClosures([2, 4, 6, 8], function(x) {
return x*x;
});
for (var i = 0; i < funcs.length; i++) {
console.log(funcs[i]());
}
输出:
4
16
36
64
它自javascript 1.8.5起作用(firefox 4)。我不知道其他浏览器,但有旧版本的实现(也应该适用于旧浏览器)