我正在为我正在循环的一些元素添加一个事件监听器,并且需要一个闭包来保留事件函数中的索引。
<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>
这两个解决方案都正确地输出0,1,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));
}