在事件触发器上将变量传递给闭包

时间:2013-10-17 17:42:24

标签: javascript functional-programming closures

我有一个循环,我为事件定义了一个闭包:

for (var i = 0; i < 3; i++) {
    obj.onload = function(e) {
        me.myFunction(e, i);
    };
}

我需要将该计数器变量传递给触发load事件时调用的函数。我总是得到相同的价值。

如何将正确的计数器值传递给函数?

1 个答案:

答案 0 :(得分:5)

解决这个问题的常用方法是使用构建器函数,以便处理程序关闭不会更改的内容:

function buildHandler(index) {
    return function(e) {
        me.myFunction(e, index);
    };
}
for (var i = 0; i < 3; i++) {
    obj.onload = buildHandler(i);
}

可以使用立即调用的函数表达式(IIFE)执行此操作,但在 theory 中,它会在每个循环上创建并抛弃一个函数(我希望大多数JavaScript这些天的引擎优化了这一点,我至少认为它更难阅读:

for (var i = 0; i < 3; i++) {
    obj.onload = (function(index) {
        return function(e) {
            me.myFunction(e, index);
        };
    })(i);
}

如果您想直接使用Function#bind,可以使用ES5功能me.myFunction,但您必须更改您期望参数的顺序({{1首先,然后事件):

index

for (var i = 0; i < 3; i++) { obj.onload = me.myFunction.bind(me, i); } 创建一个函数,在调用时调用原始函数,并将bind设置为第一个参数(所以,上面是this),然后你给它的任何进一步的参数,然后调用函数时使用的任何参数。 (这就是为什么订单me期望它们必须更改为myFunction而不是index, e。)

在旧版浏览器中,您需要一个e, i垫片。