我在函数的循环中有一个变量:
function myHandler() {
for (var i = 0; i < items.length; i++) {
var currItem = items[i];
myObj.doSomething(function(data) {
console.log("ok");
console.log("My currItem id: " + currItem.id); // the last one of all in items
}, function(e) {
console.log("error");
console.log("My currItem id: " + currItem.id); // the last one of all in items
});
}
console.log()中的 currItem.id
每次等于项目中的最后一项。明显。我试图解决这个问题:
function myHandler() {
for (var i = 0; i < items.length; i++) {
var currItem = items[i];
var currItem = (function(i2) {
return items[i2];
})(i);
myObj.doSomething(function(data) {
console.log("ok");
console.log("My currItem id: " + currItem.id); // the last one of all in items
}, function(e) {
console.log("error");
console.log("My currItem id: " + currItem.id); // the last one of all in items
});
}
仍然没有成功。为什么以及如何解决它?
答案 0 :(得分:1)
使用这样的闭包:
正在返回的内部函数将记住创建它的环境。
function myHandler() {
for (var i = 0; i < items.length; i++) {
var currItem = items[i];
myObj.doSomething((function(currItem) {
return function(data) {
console.log("ok");
console.log("My currItem id: " + currItem.id);
}
})(currItem), (function(currItem) {
return function(e) {
console.log("error");
console.log("My currItem id: " + currItem.id);
}
})(currItem));
}
}
或强>
使用[].forEach
,因为每个迭代器回调都有自己的上下文,下次迭代时不会覆盖它。
答案 1 :(得分:0)
如果doSomething
方法是异步的,意味着回调在for循环之后运行,那么currItem将始终是最后一个。
原因是闭包,回调函数有一个闭包,它保存了要执行的函数所需的所有信息,包括对变量currItem的引用。
因为它是一个引用,当循环结束时,currItem的值是最后一项,然后才会调用回调。
修复它的最简单方法是将for循环的内部调用移动到一个函数,该函数将接受变量currItem作为参数。这样变量就不会改变。
您可以使用数组的forEach函数来执行此操作:
items.forEach(function(currItem){
....
});