从Javascript闭包中循环访问外部变量

Bar*_*lom 36 javascript jquery closures loops

看到:

for (var i in this.items) {
    var item = this.items[i];
    $("#showcasenav").append("<li id=\"showcasebutton_"+item.id+"\"><img src=\"/images/showcase/icon-"+item.id+".png\" /></li>");
    $("#showcasebutton_"+item.id).click(function() {
        alert(item.id);
        self.switchto(item.id);
    });
}
Run Code Online (Sandbox Code Playgroud)

问题是警报的item.id始终是数组中最后一项的id(this.items).怎么解决?

gna*_*arf 40

你在这里遇到的问题是变量item随每个循环而变化.当您item稍后引用时,将使用它持有的最后一个值.您可以使用一种称为闭包的技术(本质上是一个返回函数的函数)来以不同的方式快速调整变量的范围.

    for (var i in this.items) {
            var item = this.items[i];
            $("#showcasenav").append("<li id=\"showcasebutton_"+item.id+"\"><img src=\"/images/showcase/icon-"+item.id+".png\" /></li>");
            $("#showcasebutton_"+item.id).click( 
                // create an anonymous function that will scope "item"
                (function(item) {
                   // that returns our function 
                   return function() {
                    alert(item.id);
                    self.switchto(item.id);
                   };
                })(item) // immediately call it with "item"
            );
    }
Run Code Online (Sandbox Code Playgroud)

旁注 - 我看到你在这里有jQuery.它有一个$.each()可以与数组一起使用的辅助函数,并且可以是简单for/each循环的快捷方式.由于在此调用中作用域的工作方式 - 您不需要使用闭包,因为"item"在调用时已经是函数的参数,而不是存储在var父函数的作用域中,就像在您的示例中一样.

$.each(this.items,function(i, item) {
  $("#showcasenav").append("<li id=\"showcasebutton_"+item.id+"\"><img src=\"/images/showcase/icon-"+item.id+".png\" /></li>");
  $("#showcasebutton_"+item.id).click(function() {
    alert(item.id);
    self.switchto(item.id);
  });
});
Run Code Online (Sandbox Code Playgroud)