0

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

<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(尝试“错误”以查看没有关闭会发生什么),但我试图了解我应该使用哪一个以及为什么。

哪种方式是正确的做法?

4

2 回答 2

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/

于 2013-06-05T12:54:27.420 回答
1

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

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

于 2013-06-05T12:52:56.287 回答