2011-03-13 47 views
1

我以爲我理解JavaScript關閉,但顯然我不知道。從我的代碼以下面的摘錄:在這個例子中,我如何誤解JavaScript關閉解析?

for(var i=0; i<data.List.length; i++) { 
    var entry = data.List[i]; // I thought this line should have resolved the issue? 
    $('<tr class="logs-list-item"><td class="lefticon nowrap"><a href="javascript:void(0)"></a></td><td class="right nowrap"></td></tr>') 
     .appendTo(tbody) 
     .find('a').text(entry.Text) 
     .click(function() { 
      alert(entry.Text + ' ' + entry.Filename); 
      showLog(id, entry.Filename); 
     }) 
     .closest('tr').find('td:last').text(entry.When); 
} 

正如你所看到的,我們通過文件名條目列表進行迭代,並添加一個錶行,並與一些文本的每個條目描述文件和onclick處理程序對於每個應該調用函數showLog()的條目以及所選文件名的詳細信息。

什麼是實際上發生的情況是所有行都正確添加,但是其中每個行都被分配了列表中最後一項的處理程序。

第2行我在for循環中定義了一個變量,並在閉包中訪問該變量,但實際調用該函數時似乎並沒有正確解析。

任何想法我做錯了什麼?

回答

4

Javascript沒有塊級的範圍。
儘管變量是在循環內部定義的,但它仍然是共享的。

您需要將循環體移動到單獨的函數中。

+1

啊,現在我突然明白,爲什麼我寫過去的JavaScript的其他位都奇怪表現。謝謝! – 2011-03-13 19:44:11

+0

你會認爲現在我們已經想出了一種方法來自動回答這個問題(所有的變體):-) – Pointy 2011-03-13 19:46:37

0

你可以試試這個代碼嗎?

function generateClickHandler(entry) { 
    return function() { 
    alert(entry.Text + ' ' + entry.Filename); 
    showLog(id, entry.Filename); 
    } 
} 


..click(generateClickHandler(entry))... 
2

對於這個工作,你需要使用這樣的事情:

for(var i=0; i<data.List.length; i++) { 
    (function(entry){ 
     // your code goes here 
    })(data.List[i]); 
}