0

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)).

Christian
  • 6,070
  • 11
  • 53
  • 103
  • 1
    This is a common duplicate: the listener has a closure to *i* in the function that assigns the listeners so it gets the final value of *i*, which is 2. – RobG Apr 19 '16 at 22:39
  • 1
    In a word, closures. Take a look at [this question](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example). – AdmiralFailure Apr 19 '16 at 22:41
  • OK. That's on the lesson plan for tomorrow, I think. As for duplicates, it's hard to find the right answer if you don't know what you are looking for... :) If it's already there, maybe we can close this one (with a link to a good answer)? – Christian Apr 19 '16 at 22:42
  • @AdmiralFailure—leads to a great trail of answers—duplicates of duplicates of duplicates… ;-) – RobG Apr 19 '16 at 22:42
  • @RobG - I know, spotted that just after I added the comment... Edited! – AdmiralFailure Apr 19 '16 at 22:43

0 Answers0