我想将一个函数设置为数组中每个元素的属性,但是使用不同的参数调用它。我以为我会用匿名函数来解决它:
for ( var i = 0; i < object_count; i++ ) {
objects[i].callback = function(e,x,y){ cb(e,x,y,i) };
}
但是,使用i
当时具有的值调用该函数。我如何保留上下文?
答案 0 :(得分:10)
您可以将作业至少包含在一个函数或右侧:
objects[i].callback = (function(i) { return function(e, x, y) {
cb(e, x, y, i);
})(i);
立即调用“外部”匿名函数,将循环变量“i”复制到一个参数中(我也称之为“i”;有些人认为这样做会让人感到困惑,而其他人则认为它令人困惑不是< / em>这样做,所以你可以决定:-)然后由返回的“内部”匿名函数使用。
解决此问题的另一种方法是使用实用程序函数来代替简单的内联匿名函数。在这种情况下,它有点棘手,因为你希望“i”成为实际回调函数的 last 参数。 Functional JavaScript库有一个很酷的实用程序,它允许您使用固定值“预填充”函数的选定参数,为您提供一个函数,允许您将参数传递给非固定的参数;它看起来像这样:
objects[i].callback = (function(e, x, y, i) { return cb(e, x, y, i); }).partial(_, _, _, i);
无论是好还是坏都是风格和观点的问题。
编辑只是喝了一点咖啡 - 我觉得我有点傻了,以至于我不得不在上面使用“partial()”。内部(“真实”函数)在参数列表的末尾想要“i”的事实与需要设置事物的方式无关。以上示例也可以这样做:
objects[i].callback = (function(i, e, x, y) { return cb(e, x, y, i); }).curry(i);
这不那么奇怪。 (要么会工作。至少,我认为他们会。: - )
答案 1 :(得分:3)
写作时
for (var i = something; ...) {
a[i] = function() { x(i); }
}
函数中的i
对于所有函数都是相同的(它是您在for
循环范围内定义的相同变量。
您要做的是拥有一个特定于每个函数上下文的变量。你可以做这样的事情
for (var i = something; ...) {
(function () { // using an anonymous function, we create a private context
var new_i = i; // new_i has the value of 'i' but exists solely in this
// private context
a[i] = function() { x(new_i); }
// the assigned function now refers a variable of the private
// context, which will be different on the following loop
// iterations
})();
}
通过搜索JavaScript中闭包和范围的工作方式,您可以获得有关此主题的更多信息。