I’m relatively new to JS so this may be a common problem, but I noticed something strange when dealing with for loops and the onclick function. I was able to replicate the problem with this code:
<html>
<head>
<script type="text/javascript">
window.onload = function () {
var buttons = document.getElementsByTagName('a');
for (var i=0; i<2; i++) {
buttons[i].onclick = function () {
alert(i);
return false;
}
}
}
</script>
</head>
<body>
<a href="">hi</a>
<br />
<a href="">bye</a>
</body>
</html>
When clicking the links I would expect to get ‘0’ and ‘1’, but instead I get ‘2’ for both of them. Why is this?
BTW, I managed to solve my particular problem by using the ‘this’ keyword, but I’m still curious as to what is behind this behavior.
You are having a very common closure problem in the
forloop.Variables enclosed in a closure share the same single environment, so by the time the
onclickcallback is executed, the loop has run its course and theivariable will be left pointing to the last entry.You can solve this with even more closures, using a function factory:
This can be quite a tricky topic, if you are not familiar with how closures work. You may to check out the following Mozilla article for a brief introduction:
Note: I would also suggest not to use
varinside theforloop, because this may trick you in believing that theivariable has block scope, when on the other hand theivariable is just like thebuttonsvariable, scoped within the function.