关于javascript:var a = function()vs函数a()用于事件监听器?

var a = function() vs function a() for event listener?

我正在尝试理解向事件监听器添加函数时的区别以及它具有的含义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);
}

http://jsfiddle.net/paptd/

第一个按钮触发console.log 3次,而第二个按钮仅触发一次。

在正常情况下向事件侦听器添加函数时,为什么以及应该使用什么?


好吧,几个笔记:

  • 第一个在每次迭代中创建一个新的log函数,因此每次添加另一个事件监听器时,它都会添加一个新函数。
  • 第二个创建一个全局(读取提升)log函数,如果多个相同的EventListener在具有相同参数的同一EventTarget上注册,则丢弃重复的实例。 它们不会导致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.

感谢Rob W.

所以第二次和第三次迭代什么都不做。

  • 你也有关闭的问题,最后一次迭代将i设置为3,这就是控制台中显示的内容。

带闭合的固定版本:

1
2
3
4
5
6
7
8
9
10
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);
}

DEMO