Reputation: 467
Could anyone explain why the trace result of the code below are "5,5,5,5,5" rather than "1,2,3,4,5" and how do you make the anonymous function refer the collect element in the array?( in this example, "var item" should be referring list[0],[1],[2],[3],[4]).
var list:Array=[1,2,3,4,5];
var funcs:Array=[];
for each(var item:int in list){
funcs.push( function(){
trace(item);
});
}
for each(var func:Function in funcs){
func();
}
trace result: 5,5,5,5,5
Upvotes: 3
Views: 446
Reputation: 9934
The problem with your code is that you create a closure which you access later. For what you want to do you need to create multiple closures that can be later accessed.
var list:Array=[1,2,3,4,5];
var funcs:Array=[];
var closure_factory = function(index) {
return function() { trace(index); };
};
for each(var item:int in list){
funcs.push(closure_factory(item));
}
for each(var func:Function in funcs){
func();
}
Upvotes: 3
Reputation: 2363
This is the result of two things:
Function-level scope in AS3: the variable declaration inside for each(var item:int in list)
is equivalent to declaring a var item:int
at the beginning of your function (in your example, at the start of your code).
Anonymous functions are closures, which contain not only the code that you specify trace(item)
, but also the environment for that code to run in. Specifically, each of the anonymous functions created by your code knows that it should use the item
variable (declared at function scope) for printing (via trace()
).
So, what happens is that item
gets assigned all the elements of list
, and then retains the last value (which is 5). It exists (does not go out of scope), and when those anonymous functions fire, each of them looks at the same item
and prints the same value.
Upvotes: 2