JQuery deferred - variable scope in deferred getJSON success functions

I am adding deferred getJSON calls to an array inside a for loop that references local variables inside their success function. The problem that I encountered is that when the success function is called, the local variable takes the value from the last iteration of the loop. Example below:

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 warnings with a value of "c", while I need the values โ€‹โ€‹of "a", "b" and "c". Is it possible?

EDIT: The below works, but I'm not quite sure why this is different?

 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/

0
source share
1 answer

See what a loop is:

 var a = []; for( var i = 0; i < 3; ++i ) { a.push( function() { alert(i); }); } 

actually:

 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 why all the functions alert 3, because they all //refer to this i and its value is 3 

Now you can do it instead (repeat 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)); 
+1
source

All Articles