It seems I don’t understand javascript callbacks quite as well as I thought.
In the following example, I would think that each copy of function in setTimeout would refer to its own copy of the variable ‘index’. Therefore, running the example should produce the following alerts: ‘zero’ ‘one’ ‘two’.
var array = ['zero', 'one', 'two']; var out = ''; for(var i = 0; i < 3; i++){ var index = i; setTimeout( function(){alert(array[index])}, 1 ); }
However, it seems that theres only one copy of the index variable, and all copies of the callback function point to the same variable, giving me the following alerts: ‘two’ ‘two’ ‘two’.
The following analagous (I thought) example in java prints ‘zero’ ‘one’ ‘two’, as expected.
import java.util.ArrayList; import java.util.List; public class CallBacks { public static void main(String[] args) { String[] array = {'zero', 'one', 'two'}; List<Callback> callBacks = new ArrayList<Callback>(); for(int i = 0; i<3; i++){ final String print = array[i]; callBacks.add( new Callback(){ public void execute(){ System.out.println(print); } } ); } for(Callback cb : callBacks){ cb.execute(); } } private interface Callback{ public void execute(); } }
Can anyone explain to me why the js example doesn’t work, and perhaps compare what’s going on in the two examples?
indexchanges with each iteration of the loop. What you want is to placeindexinto a closure not affected by the loop: