问题
I am adding deferred getJSON calls to an array inside a for loop that reference local variables inside their success function. The problem I am having is that when the success function is called, the local variable is taking the value from the last iteration of the loop. See below example:
var calls = [];
var arr = ['a','b','c'];
for (var a in arr) {
calls.push(
$.getJSON(window.location, function() { alert(arr[a]); })
);
}
$.when.apply($,calls);
jsFiddle: http://jsfiddle.net/Me5rV/
This results in three alerts with the value 'c', whereas I would like the values 'a', 'b', and 'c'. Is this possible?
EDIT: The below works, but I'm not entirely sure why this differs?
var calls = [];
var arr = ['a','b','c'];
for (var a in arr) {
calls.push(
$.getJSON(window.location, function(x) {
alert(x);
}(arr[a]))
);
}
$.when.apply($,calls);
jsFiddle: http://jsfiddle.net/Me5rV/1/
回答1:
Review what a loop like this:
var a = [];
for( var i = 0; i < 3; ++i ) {
a.push( function() {
alert(i);
});
}
actually does:
var a = [], i = 0;
a.push( function(){
alert(i);
});
i++;
a.push( function() {
alert(i);
});
i++;
a.push( function() {
alert(i);
});
i++;
//condition isn't met, loop terminates
alert(i) //alerts 3 because i is 3 now.
//That's why all the functions alert 3, because they all
//refer to this i and its value is 3
Now you could do this instead (repetition removed):
a.push( function(i){
return function() {
alert(i); //Refers to the i passed as argument to the outer function
//not the global one
//The local i has whatever value the global i had when it was passed
//as argument
};
}(i));
来源:https://stackoverflow.com/questions/11903649/jquery-deferred-variable-scope-in-deferred-getjson-success-functions