2010-07-27 151 views
6

有兩個版本,據說當用戶單擊第一個鏈接,它會提醒「1」,第二個環節,「2」等:爲什麼一個JavaScript關閉工作,另一個不工作?

版本1:

<a href="#" id="link1">click me</a> 
<a href="#" id="link2">click me</a> 
<a href="#" id="link3">click me</a> 
<a href="#" id="link4">click me</a> 
<a href="#" id="link5">click me</a> 

<script type="text/javascript"> 
    for (i = 1; i <= 5; i++) { 
     document.getElementById('link' + i).onclick = (function() { 
      return function() { 
       var n = i; 
       alert(n); 
       return false; 
      } 
     })(); 
    } 
</script> 

版本2:

<a href="#" id="link1">click me</a> 
<a href="#" id="link2">click me</a> 
<a href="#" id="link3">click me</a> 
<a href="#" id="link4">click me</a> 
<a href="#" id="link5">click me</a> 

<script type="text/javascript"> 
    for (i = 1; i <= 5; i++) { 
     document.getElementById('link' + i).onclick = (function() { 
      var n = i; 
      return function() { 
       alert(n); 
       return false; 
      } 
     })(); 
    } 
</script> 

版本1不起作用。版本2將。我想我知道爲什麼,但想與其他人解釋爲什麼版本1不起作用。

回答

4

版本1不起作用,因爲有一個共同的變量「i」(一全球在這種情況下變量,因爲您忘記var)由每個共享「單擊」處理函數循環造成的。

在第二個版本中,將創建的小包裝函數一個新的詞彙範圍。這給每個「點擊」處理程序它是非常私人的「我」。

3

在第二個示例中,您創建了一個變量n = i;,它使i值的範圍在onclick函數內。而在第一個的onclick函數仍使用的i

全球價值我建議這種用法,而不是:

for (i = 1; i <= 5; i++) { 
    document.getElementById('link' + i).onclick = (function(i) { 
     return function() { 
     alert(i); 
     return false; 
     } 
    })(i); 
    } 

在這種情況下,你會得到相同的行爲,因爲i將是局部變量用於onclick函數,因爲它是一個參數。

0

先不工作,因爲我是每一個封閉的一部分。經過5次迭代後,我現在是6,因爲後綴增量運算符。因爲每個封閉在正讓我的副本,n爲每個封閉的一部分:當事件處理程序被調用它每次從它的關閉範圍,始終是6

第二部分工作得到我的價值。

+0

從看第1版,並沒有做它的'i'太每一次一個新的副本? – 2010-07-27 13:13:54

+0

不是。在版本1中,迭代foreach時不復制。但點擊時它會複製。 – 2010-07-27 19:37:26

相關問題