2013-08-30 56 views
1

考慮以下代碼:價值嵌套函數變量的評價在定義時,而不是在calltime

for(var i = 1; i <= 2; ++i) 
{ 
$('#id' + i).click(
    function() 
    { 
    alert('ID = ' + i); 
    } 
) 
} 

的問題是,當ID1或ID2點擊警報總是說,ID = 3。現在我知道爲什麼發生這種情況(它在通話時進行評估),我只是好奇,如果有什麼方法來防止這種情況發生? (1)

這裏的很多問題和一般性文章都很好地解釋了關閉的概念,但是我一直無法找到任何技術來避免它。

在一個側面說明,我試圖用(注意額外的關鍵詞「新」):

new function() { alert('ID = ' + i) } 

但是直接在它被定義的時候調用警報並執行上點擊事件罷了。對此有何想法? (2)

+0

參見:http://stackoverflow.com/questions/1451009/javascript-infamous-循環問題 – bfavaretto

回答

1

基本上你需要創建一個新的範圍,其中的i值不會改變。因此,爲了說明這一點,你可以創建一個外循環功能,使電流值:

function createClickAction(i){ 
    return function(){ 
     alert('ID = ' + i); 
    } 
} 

for(var i = 1;i <= 2; ++i){ 
    $('#id' + i).click(
     createClickAction(i) 
    ); 
} 

但較短的方式做同樣的事情到值傳遞到IIFE

for(var i = 1;i <= 2; ++i){ 
    (function(i){ 
     $('#id' + i).click(
      function(){ 
       alert('ID = ' + i); 
      } 
     ); 
    })(i); 
} 

下面是關於語法的一些討論new function(){...}
它與IIFE具有相同的效果,因爲您將實例化一個自治函數作爲構造函數。所以這就像說:

function Message(){ 
    alert('hi'); 
} 
new Message(); 

...但沒有命名。
並傳遞參數在:

new function(msg){ 
    alert(msg) 
}('hi'); 

所以,你很可能接近找到這個解決方案:

for(var i = 1;i <= 2; ++i){ 
    new function(i){ 
     $('#id' + i).click(
      function(){ 
       alert('ID = ' + i); 
      } 
     ); 
    }(i); 
} 
+0

謝謝。很好解釋。 – NeverStopLearning

0

怎麼樣 -

for(var i = 1; i <= 2; ++i) 
{ 
$('#id' + i).click(
    function() 
    { 
    alert('ID = ' + this.id.substring('#id'.length)); 
    } 
) 
} 
+0

謝謝。這(很可能)適用於我給出的示例。然而,我一般對解決方案概念感興​​趣(例如參見robC的答案)。 – NeverStopLearning

2

一種方式會是這樣。

HTML

<div id="id1">ID1</div> 
<div id="id2">ID2</div> 
<div id="id3">ID3</div> 

的Javascript

for (var i = 1; i <= 2; i += 1) { 
    (function (j) { 
     $('#id' + j).click(

     function() { 
      alert('ID = ' + j); 
     }); 
    }(i)); 
} 

jsfiddle

+0

謝謝你的工作解決方案。我選擇robC的答案是因爲它更具描述性。 – NeverStopLearning