在这个例子中,我如何误解JavaScript闭包解析?

时间:2011-03-13 19:36:57

标签: javascript closures

我以为我理解了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处理程序{{ 1}}包含所选文件名的详细信息。

实际发生的是所有行都正确添加,但每个行都被分配了列表中最后一项的处理程序。

在第2行我在for循环中定义一个变量并在闭包内访问该变量,但是当实际调用该函数时,它最终似乎没有正确解析。

任何想法我做错了什么?

3 个答案:

答案 0 :(得分:4)

Javascript没有块级范围。
即使变量是在循环内定义的,它仍然是共享的。

您需要将循环体移动到单独的函数。

答案 1 :(得分:2)

为此,您需要使用以下内容:

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

答案 2 :(得分:0)

你能试试那段代码吗?

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


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