将超出可变范围

时间:2011-03-08 09:29:15

标签: javascript loops closures

我有以下源代码:

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

现在,如果我点击每个链接,浏览器会显示相同的结果

  

TEMP3

我使用Firebug来分析代码,我发现他获取变量i的最后一个值。我的问题是 1为什么浏览器总是使用变量中的最后一个值? 2我如何更改源代码,因此浏览器会显示'temp1','temp2'等?

由于

3 个答案:

答案 0 :(得分:2)

我确定stackoverflow.com中有欺骗行为。我在另一个标签中提供了该链接,因此这里是:Creating closures in loops - common mistake

这是一个骗局:Stackoverflow.com - Please explain use of javascript closures in loops - 它提供了解决问题的两种主要方法。

答案 1 :(得分:2)

onclick功能仅将引用抓取到i,而不是其值的副本。由于值在循环迭代中不断变化,并且由于onclick函数在发生这种情况后被调用,因此i的值始终为links.length

要解决此问题,您需要保留变量的副本。一种常见的方法是将函数包装在另一个函数中,即创建并立即调用该函数,并传入当前值i

(function (new_i) {
    link.onclick = function() {alert("temp" + new_i); return false;}; 
})(i);

答案 2 :(得分: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>