Reputation: 221
I'm having trouble understanding why the "duplicate" event listeners created in the following examples behave so differently. I've perused several discussions about the topic, but I'm just starting to learn JavaScript, and I can't quite figure out what's happening in Version 2 that isn't happening in Version 1. Would anyone be willing to enlighten me?
Here's a JSFiddle demo. The JavaScript looks like this:
// VERSION 1
var clickEvents = 0;
button.addEventListener('click', buttonFunction);
function buttonFunction() {
clickEvents++;
display.innerHTML = clickEvents; // <-- increases incrementally
button.addEventListener('click', buttonFunction);
}
// VERSION 2
var clickEvents = 0;
mainFunction();
function mainFunction() {
button.addEventListener('click', buttonFunction);
function buttonFunction() {
clickEvents++;
display.innerHTML = clickEvents; // <-- increases exponentially
mainFunction();
}
}
Upvotes: 1
Views: 2017
Reputation: 4603
The behavior is due to scoping. In version 1, you're adding the globally scoped function . When you try to add it again it silently fails because the function is already registered. From MDN:
Multiple identical event listeners
If multiple identical EventListeners are registered on the same EventTarget with the same parameters, the duplicate instances are discarded. They do not cause the EventListener to be called twice, and they do not need to be removed manually with the removeEventListener method.
In version 2, because the buttonFunction
declared inside mainFunction
is locally scoped it is not the same as the global function and every time you call it mainFunction
you get a different version since the scope is changing. Because the JS Engine considers the functions to be different when you call addEventListener
each one is added independantly. Every time you click the button you're doubling the number of listeners attached to the button.
The snippet demonstrates that the JS Engine considers each invocation of bar()
to have a different local foo
function foo() {
console.log("global");
}
function bar() {
function foo() {
console.log("local");
}
return foo;
}
var oneG = foo;
var twoG = foo;
var oneL = bar();
var twoL = bar();
console.log(`Global: ${oneG === twoG}`);
console.log(`Local: ${oneL === twoL}`);
Upvotes: 1