I have seperated your functions into incorrect
and correct
one.
The incorrect
version is what you're asking. The correct
version is what you've already figured out but don't know why it work.
In the incorrect version, the value of i
will always be updated to the most recent value because i
belongs to the createButtons
function and is shared with all onclick
handler, and it is changing with the loop.
In the correct version, the value of i
is given to the IIFE as num
, and num
belongs to the IIFE and not to createButtons
.
Because of that, num
is fixed because a new num
is created for every loop thus is not shared with the other onclick
handler.
Why? It is how closure works in JavaScript.
Read this for deeper understanding on JavaScript closure.
function createButtons_incorrect() {
for (var i = 1; i <= 5; i++) {
var body = document.getElementsByTagName("BODY")[0];
var button = document.createElement("BUTTON");
button.innerHTML = 'Bad ' + i;
button.onclick = function() {
alert('This is button ' + i);
}
body.appendChild(button);
}
}
function createButtons_correct() {
for (var i = 1; i <= 5; i++) {
var body = document.getElementsByTagName("BODY")[0];
var button = document.createElement("BUTTON");
button.innerHTML = 'Good ' + i;
(function(num){
button.onclick = function() {
alert('This is button ' + num);
}
})(i);
body.appendChild(button);
}
}
createButtons_incorrect();
document.body.appendChild(document.createElement('br'));
createButtons_correct();