如何在整个循环中正确引用对象?

时间:2012-01-28 01:12:01

标签: javascript jquery scope

请参阅http://jsfiddle.net/tAfkU/

当我循环遍历数组时,当我在循环中绑定回调时,如何引用数组的正确元素?

var items = ["a", "b", "c"];
for(var i in items) {
    var this_item = items[i];
    var new_li = $('<li>'+this_item+'</li>');
    new_li.bind('click', function() {
        alert(this_item); // this always alerts "c"
    });
    $('.container').append(new_li);
}

3 个答案:

答案 0 :(得分:3)

您需要在该变量上创建一个闭包:

var createCallback;

createCallback = function(item) {
  return function() {
    alert(item);
  };
};
for(var i in items) {
    var this_item = items[i];
    var new_li = $('<li>'+this_item+'</li>');
    new_li.bind('click', createCallback(this_item));
    $('.container').append(new_li);
}

请记住,稍后调用绑定函数,然后该循环结束,因此this_item的值是最后设置的值。 Javascript不会为每个循环迭代创建一个新的范围,因此如果要定义回调,则必须自己创建一个。在JS中创建范围的唯一方法是通过函数。所以我写了一个函数,它将值绑定为一个参数,并返回一个新的函数,现在将“记住”正确的值。

答案 1 :(得分:0)

问题是您将所有元素“点击”绑定到同一个变量。而且,由于每次迭代数组中的值时都定义此变量,因此单击将始终返回分配给变量的最后一个值(c)。

以下是获取实际“值”的解决方案,因为您在列表项中设置了它,您只需获取实际对象并返回.text();

var items = ["a", "b", "c"];
for(var i in items) {
    var this_item = items[i],
        new_li = $('<li>'+this_item+'</li>');
    new_li.bind('click', function() {
        alert($(this).text());

        //alert(this_item); // this always alerts "c"
    });
    $('.container').append(new_li);
}

答案 2 :(得分:-1)

尝试在jQuery中使用.data()方法。

var items = ["a", "b", "c"];
for(var i in items) {
    var this_item = items[i];
    var new_li = $('<li>'+this_item+'</li>');
    new_li.data("item", this_item).bind('click', function() {
        alert($(this).data("item"));
    });
    $('.container').append(new_li);
}