Today I came across a strange behaviour in JavaScript when I was adding a function to an onclick event.
Let me explain:
When dynamically creating some buttons and adding a function to their onclick events, like this:
function createButton(a) {
button = document.createElement("button");
button.setAttribute("id","a"+a);
button.innerHTML = "a"+a;
button.onclick = function () {
alert("Should be the same: a"+a+" and "+this.id);
};
return button;
}
for (var a=0;<3=;a++) {
document.body.appendChild(createButton(a));
}
I get this message when pressing the first button:
"Should be the same: a0 and a0"*, as expected.
But when I want to do the same thing without using a separate function (createButton) like this:
var button;
for (var a=0;a<=3;a++) {
button = document.createElement("button");
button.setAttribute("id","a"+a);
button.innerHTML = "a"+a;
button.onclick = function () {
alert("Should be the same: a"+a+" and "+this.id);
};
document.body.appendChild(button);
}
a=999;
Now I got this message when pressing the first button:
"Should be the same: a999 and a0"*.
Does anyone know why they doesn’t produce the same alerts? And is there any way of making the second example work like the first one? (i know that
button.onclick = "alert('Should be the same: a"+a+" and "+this.id+"')) does the trick, but that’s just ugly)
Any help would be appreciated, the script may be viewed at http://xc-results.com/static/stackoverflowq1.htm
In the second example,
button.onclickis a closure: a function + some bounded variables (in this case,a). That means thatawill be evaluated at the momentonclick()is evaluated, not at the moment it is defined. At the momentbutton.onclickis ran,aequals 999, hence your result.