我正在尝试理解向事件监听器添加函数时的区别以及它具有的含义.
var buttons = document.getElementsByTagName('button');
for (i = 0,len = 3; i < len; i++) {
var log = function(e) {
console.log(i);
}
buttons[0].addEventListener("click",log);
}
for (i = 0,len = 3; i < len; i++) {
function log(e) {
console.log(i);
}
buttons[1].addEventListener("click",log);
}
第一个按钮触发console.log 3次,而第二个按钮仅触发一次.
最佳答案
好吧,几个笔记:
>第一个在每次迭代中创建一个新的日志函数,因此每次添加另一个事件监听器时,它都会添加一个新函数.
>第二个创建全局(读取提升)日志函数,如果在具有相同参数的同一EventTarget上注册了多个相同的EventListener,则会丢弃重复的实例.它们不会导致EventListener被调用两次.
眼镜:
Invoking addEventListener (or removeEventListener) repeatedly on the same EventTarget with the same values for the parameters type,listener,and useCapture has no effect. Doing so does not cause the event listener to be registered more than once and does not cause a change in the triggering order.
source感谢Rob W.
所以第二次和第三次迭代什么都不做.
>您也有关闭问题,最后一次迭代将i设置为3,这就是控制台中显示的内容.
带闭合的固定版本:
var buttons = document.getElementsByTagName('button');
for (i = 0,len = 3; i < len; i++) {
var log = (function closure(number) {
return function () {
console.log(number);
}
})(i);
buttons[0].addEventListener("click",log);
}