0

I've got follow source code:

<html>
<head><script type="text/javascript"> 
      function test() 
      { 
        var links = document.getElementsByTagName('a'); 
        for(var i=0; i< links.length; i++) 
        { 
          var link = links[i]; 
          if(link.href) 
          { 
            link.onclick = function() {alert("temp" + i); return false;}; 
          }; 
        }; 
      };
    </script> 
  </head> 
  <body onLoad="test()"> 
    <p><a href="javascript.html">test1</a></p> 
    <p><a href="javascript.html">test2</a></p> 
    <p><a href="javascript.html">test3</a></p> 
  </body> 
</html>

Now, if I click on each link, the browser shows me the same result

temp3

I used Firebug to profile the code and I figured out that he takes the last value of variable i. My questions are 1st Why does the browser use the always the last value from the variable? 2nd How have I change the source code, so the browser will show me 'temp1', 'temp2', etc. ?

Thanks

Anurag
  • 140,337
  • 36
  • 221
  • 257
Reporter
  • 3,897
  • 5
  • 33
  • 47
  • see all [related questions](http://stackoverflow.com/questions/tagged/javascript+closures+loops). – Anurag Mar 08 '11 at 09:40

3 Answers3

2

I'm sure there are dupes in stackoverflow.com. I've got the link available in another tab, so here it is: Creating closures in loops - common mistake

Here's a dupe: Stackoverflow.com - Please explain use of javascript closures in loops - which gives the two main ways of fixing the problem.

Community
  • 1
  • 1
typo.pl
  • 8,812
  • 2
  • 28
  • 29
2

The onclick function only grabs a reference to i, and not a copy of its value. As the value keeps changing through iterations of the loop, and since the onclick function is called after this happens, the value of i will always be links.length.

To fix this, you want to preserve a copy of the variable. A common approach is to wrap the function in another one, that is created and called immediately, passing in the current value of i:

(function (new_i) {
    link.onclick = function() {alert("temp" + new_i); return false;}; 
})(i);
David Tang
  • 92,262
  • 30
  • 167
  • 149
0
<html>
<head><script type="text/javascript"> 
      function test() 
      { 
        var links = document.getElementsByTagName('a'); 
        for(var i=0; i< links.length; i++) 
        { 
          var link = links[i]; 
          if(link.href) 
          { 

              link.onclick = (function(i) { return
                  function() {alert("temp" + i); return false;}; }) (i);
          }; 
        }; 
      };
    </script> 
  </head> 
  <body onLoad="test()"> 
    <p><a href="javascript.html">test1</a></p> 
    <p><a href="javascript.html">test2</a></p> 
    <p><a href="javascript.html">test3</a></p> 
  </body> 
</html>
wnrph
  • 3,293
  • 4
  • 26
  • 38