I’ll try to explain what’s going on in the code.
The first point worth noting is the "Declaration Hoisting":
https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
Which means the elevation of variable declarations to the top of the scope, which can be global or function. That is to say:
for(var i=0; i < nums.length; i++)
It’s like doing:
var i;
for(i = 0; i < nums.length; i++)
This way the variable i will be available for use by everyone within the scope.
And for this reason that by adding a click this way:
elem.addEventListener('click', function() {
alert(nums[i])
});
It will always result in the last number being displayed. Because the anonymous function you created has access to variables i and nums that were in the same scope as the anonymous function. Meaning that at the moment the function is executed the variable i contains the index of the last element of the Array.
IIFE
To mitigate this problem, we use an IIFE (Immediately Invoked Function Expression), a function that is executed immediately upon being created. Usually expressed in this way:
(function(){
}())
Or
(function(){
})()
Although I personally prefer the first option. By doing what you demonstrate in the code, the following happens:
IFFE shall be implemented during the loop and takes as parameter the value contained in the current index of the Array;
elem.addEventListener('click', (function(num) {
})(nums[i]));
As a new function has been declared, a new scope is created. This scope has a variable called in a that contains the value contained in the index of the array with which the function was called.
You return a new function that when executed will call the function Alert, passing one as parameter;
return function() {
alert(num);
};
This new function, which was created in the clause Return is then added as event manager;
elem.addEventListener('click', (function(num) {
return function() {
alert(num)
};
})(nums[i]));
In your case, when clicking always displays the last number of the Array because, from what I understand, you call the addeventlistener several times in the same element. Thus, when adding a new Istener, the old one is overwritten.