Javascript中循环的奇怪行为

时间:2013-11-26 03:36:34

标签: javascript for-loop closures

以下代码是生成公告板列表。它适用于查看内容(例如,postId0,postId1,...),但就好像'我'是nPosts

我记得在C#中我遇到了同样的问题并通过声明i的副本(var copy_i = i;在循环中)来修复,但是这里也没有用。

function loadList() {
    $.getJSON("list.php", function (json) {
        var nPosts = json.length;
        for (var i = 0; i < nPosts; i++) {
            var post = $('<ol/>', {
                class: "viewPost",
                id: "post" + i
            }).appendTo("#viewList");

            $('<li/>', {
                class: "viewPostId",
                id: "postId" + i,
                text: json[i].noteId
            }).appendTo("#post" + i);

            var memo = $('<li/>', {
                class: "viewMemo",
                id: "memo" + i,
                text: json[i].noteContent
            }).appendTo("#post" + i);

            //alerts 'nPosts' for every i.
            memo.on("click", function () { alert(i); });
        }
    });
}

2 个答案:

答案 0 :(得分:2)

正如预期的那样,问题在于无法预料的关闭。这一行:

memo.on("click", function () { alert(i); }); 

i变量上创建一个闭包,在调用click处理程序之前,该变量一直递增到最大值。

以下是如何为您的处理程序提供“虚拟变量”:

var handlerCreator = function (counter) { 
    return function(){
        alert(counter); // The handler now closes over the counter variable, 
                        // which cannot be accessed by other code and therefore
                        // retains the value passed in to this function (i.e. the
                        // value of i on the current iteration)
    }; 
}
memo.on("click", handlerCreator(i));

答案 1 :(得分:1)

警告i的点击功能在循环完成后执行,因此它将等于nPosts