I'm perplexed as to why I have to wrap my alert in a function in order to avoid my code ignoring the event listener.
If I run this code, It'll work properly and I'll be able to click and have the alert display after the click
elem.addEventListener('click', (function(numCopy) {
return function() {
alert(numCopy);
};
})(num));
But if I run this code, it'll ignore the event listener and display the alert as soon as the page loads
elem.addEventListener('click', (function(numCopy) {
return alert(numCopy);
})(num));
I could ignore it and just accept this is the way it's done but I would really appreciate it if someone could explain the logic behind this so I can fully grasp the concept, thanks a lot in advance.
Lets figure out what's going on by looking at the following example:
function foo(x) {
return x;
}
var bar = foo(42);
baz(bar);
What is the value passed to baz
? 42
because foo
simply returns the value passed to it.
Now lets inline the function call:
function foo(x) {
return x;
}
baz(foo(42));
What is the value passed to baz
here? Still 42
whether we assign the return value to a variable or directly pass it to the other function doesn't make a difference.
Now lets inline the function definition:
baz(function foo(x) { return x; }(42));
Now we have an IIFE. What is the value passed to baz
here? Still 42
. We didn't actually change what the code is doing, we just got rid of intermediate variable assignments (we could also drop foo
from the function expression).
How does this related to your code? Lets work our way backwards from your code. We start with:
elem.addEventListener('click', (function(numCopy) {
return alert(numCopy);
})(num));
Lets extract the function definition:
function foo(numCopy) {
return alert(numCopy);
}
elem.addEventListener('click', foo(num));
Now lets extract the function call:
function foo(numCopy) {
return alert(numCopy);
}
var bar = foo(num);
elem.addEventListener('click', bar);
Do you see what's wrong here? You are calling the function (foo
in this case). The function executes alert
and that's why you immediately see the alert.
foo
returns the return value of alert
(assigned to bar)
, so you are passing that value to addEventListener
.
But alert
returns undefined
whereas addEventListener
expects to be passed a function.
That's why your IIFE needs to return a function.