I have the following code:
<html>
<body>
<p>para 1</p>
<p>para 2</p>
<script>
var allP = document.getElementsByTagName("p");
for (var i = 0; i < allP.length; i++) {
console.log(i);
allP[i].onclick = function () {
alert("p" + i + " was clicked."); // expected: i = 0..n-1; actual: i = n
}
}
</script>
</body>
</html>
When I open the console, I can see that the loop iterated over both paragraph tags: 0
and 1
are printed to the log.
When I click the first p tag, I would now expect to get an alert with the message "p0 was clicked." What I get, however, is "p2 was clicked."
Why? I'd assume that, when I pass "p" + i + " was clicked."
to alert
, i
would get converted to a string - but it seems to be a reference to the Number object stored in i
(that gets converted on the fly when the anonymous function is called) - which is, of course, n
(i.e. allP.length
) after the loop runs.
Can someone please explain to me what's going on (and when the argument to alert is "constructed"/evaluated), what this behaviour is called (I don't think a compiled language like Java, or an interpreted one like PHP3/4, would behave that way?), and what I'd need to do to get the behaviour I was expecting (i.e. have the alert message refer to the clicked element's index (without having to write each message out statically myself)).