从Javascript闭包访问循环中的外部变量
见:从Javascript闭包访问循环中的外部变量,javascript,jquery,loops,closures,Javascript,Jquery,Loops,Closures,见: for(此.items中的变量i){ var项目=本项目[i]; $(“#showcasenav”).append(“”); $(“#showcasebutton”+item.id)。单击(函数(){ 警报(项目id); 自动切换到(项目id); }); } 问题在于,alerted item.id始终是数组中最后一个项(this.items)的id。如何解决?试试这个循环 for (var i in this.items) { var item = this.items[i];
for(此.items中的变量i){
var项目=本项目[i];
$(“#showcasenav”).append(“”);
$(“#showcasebutton”+item.id)。单击(函数(){
警报(项目id);
自动切换到(项目id);
});
}
问题在于,alerted item.id始终是数组中最后一个项(this.items)的id。如何解决?试试这个循环
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);
});
}
for(var i=0;i
这里的问题是变量项
随每个循环而变化。当您在稍后的某个点引用项时,将使用它所持有的最后一个值。您可以使用一种称为a(本质上是一个返回函数的函数)的技术来快速确定变量的范围
for (var i=0; i < this.items.length; i++) {
this.items[i]
};
另一种方法是通过调用函数来确保有效地完成=items[i]
业务。简而言之,这是:
$.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);
});
});
for(此.items中的变量i){
(职能(项目){
$(“#showcasenav”).append(“”);
$(“#showcasebutton”+item.id)。单击(函数(){
警报(项目id);
自动切换到(项目id);
});
})(本条第[i]项);
}
那里的匿名函数有点混乱,因此最好使用一个不那么匿名的函数,但它确实起到了作用。Javascript闭包存储对其变量的引用,因此所有onclick处理程序都使用相同的变量
您需要在中间函数中捕获变量,如下所示:
for (var i in this.items) {
(function(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);
});
})(this.items[i]);
}
function buildClickHandler(pageNumber) {
return function() { //Create and return a new function
alert(item.id);
self.switchto(item.id);
}
}
然后,使用该函数创建单击处理程序,如下所示:
for (var i in this.items) {
(function(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);
});
})(this.items[i]);
}
function buildClickHandler(pageNumber) {
return function() { //Create and return a new function
alert(item.id);
self.switchto(item.id);
}
}
for(此.items中的变量i){
var项目=本项目[i];
$(“#showcasenav”).append(“”);
$(“#showcasebutton”+item.id)。单击(buildClickHandler(item));
}
每次调用buildClickHandler
都会创建一个单独的闭包,闭包有自己的变量。我很清楚这是一篇老文章,但据我所知,设计jQuery(我想你一定在使用)的天才们似乎已经为你的问题找到了最佳的解决方案
在库的新1.4版本中。这使您能够有效地修改正在调用的函数的上下文/作用域-以jQuery方式完成,从而确保您可以停止使用可能会把事情搞砸的技术。不,循环很好。问题是,每个添加的列表项在闭包中都会看到相同的“item.id”。事后为您找到了一个更优雅的解决方案-查看使用$的优势。each()
谢谢!我只是花了一段时间尝试创建一个闭包,以便在单击回调中使用局部变量。对于我来说,从返回的函数中删除参数是一个棘手的部分。