3

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
3
  • closures the item for each func is shared and shows last item value Commented Apr 5, 2013 at 8:17
  • 3
    yours is the almost exactly BAD EXAMPLE from JavaScript: The Good Parts by Douglas Crockford:) try this to fix it: var helper:Function = function(i:int):Function { return function():void { trace(i); } } then change to funcs.push( helper(item) ); what it does is pass current loop value of item tot he new closure created by helper Commented Apr 5, 2013 at 8:22
  • @Lukasz'Severiaan'Grela Still the most valuable information on this page. Commented Aug 26, 2016 at 5:41

2 Answers 2

3

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();
}
Sign up to request clarification or add additional context in comments.

Comments

2

This is the result of two things:

  1. 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).

  2. 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.

1 Comment

Thanks for the replies, this answer made me understand what was wrong with my code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.