在for循环中正确使用闭包?

时间:2013-06-05 12:49:50

标签: javascript

我正在为我正在循环的一些元素添加一个事件监听器,并且需要一个闭包来保留事件函数中的索引。

<button>solution 1</button>
<button>solution 2</button>

<script>
var buttons = document.getElementsByTagName('button');
for (var i = 0; i < 3; i++) {
    var log = (function closure(number) {
        return function () {
            console.log(number);
        };
    })(i);

    buttons[0].addEventListener("click", log);
}
for (var i = 0, len = 3; i < len; i++) {
    (function (i) {
        var log = function () {
                console.log(i);
            };
        buttons[1].addEventListener("click", log);   
    })(i);
}
</script>

http://jsfiddle.net/paptd/11/

这两个解决方案都正确地输出0,1,2(尝试“错误”以查看没有关闭时会发生什么)但我正在尝试理解应该使用哪个以及为什么。

这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

第一个可行,因为您正在定义一个闭包,从中返回一个函数,然后将该函数分配给一个监听器。

第二个似乎更合适,因为闭包包含整个循环内容,使得i的值更明显地被“锁定”在那里。

答案 1 :(得分:1)

您不应该使用任何这些 - 您在循环内创建 n 相同的函数。您应该将代码重构为返回事件处理程序的命名函数:

var buttons = document.getElementsByTagName('button');

function createHandler(number) {
    return function () {
        console.log(number);
    };
}

for (var i = 0; i < 3; i++) {   
    buttons[0].addEventListener("click", createHandler(i));
}

示例: http://jsfiddle.net/paptd/12/