2
votes

Take the following code:

   import flash.display.MovieClip;

    var q:MovieClip;

    for(var i=0;i<10;i++)
    {
        q=new MovieClip();
        q.addEventListener(Event.ADDED_TO_STAGE,function(e){trace("<<<<>"+i)});
        q.addEventListener(Event.ENTER_FRAME,function(e){trace(">"+i)});
    addChild(q);

        }

The output will be:

<<<<>0
<<<<>1
<<<<>2
<<<<>3
<<<<>4
<<<<>5
<<<<>6
<<<<>7
<<<<>8
<<<<>9
>10
>10
>10
>10
>10
>10
>10
>10
>10

Now, what is clearly seen here is that while Event.ADDED_TO_STAGE is registered correctly, Event.ENTER_FRAME is not, is only registered to the last value.

Now here gets tricky, take the following code:

import flash.display.MovieClip;

var q:MovieClip;

for(var i=0;i<10;i++)
{
    q=new MovieClip();
    q.name="q_"+i;
    q.addEventListener(Event.ADDED_TO_STAGE,function(e){trace("<<<<>"+i)});
    q.addEventListener(Event.ENTER_FRAME,function(e){trace(">"+e.target.name)});
addChild(q);

    }

The output will be:

<<<<>0
<<<<>1
<<<<>2
<<<<>3
<<<<>4
<<<<>5
<<<<>6
<<<<>7
<<<<>8
<<<<>9
>q_0
>q_1
>q_2
>q_3
>q_4
>q_5
>q_6
>q_7
>q_8
>q_9

So the conclusion is that the events are registered correctly, but in a weird way the annonymous function takes only the last value from i.

Does anyone know why this happens?
And if do, please share, but don't answer shortly like: 'Well i is computed first and is clearly that events are registered after'. I would like to know if someone has more insights about the cause and the repercussions


Edited: In the light of new answers i've edited the question since i've realised that it doesn't "hit the spot" Ok give this code:

for(var i=0;i<10;i++)
{
    var q:MovieClip;
    q=new MovieClip();
    var dummy:int;
    dummy = 6+i;
    q.addEventListener(Event.ENTER_FRAME,function(e){trace(dummy);});
    addChild(q);

    }

dummy is created as new var, thus a new pointer inside the the loop at each iteration. So normally the dummy inside the function should be different. Still is the same dummy.

Now after more tests i've realised that in case of ' for {var x} ' the compiler uses the var keyword only once, so basically it changes in something like 'var x;for{}'


2

2 Answers

3
votes

i is evaluated when the function is called, not when it is declared. The ADDED_TO_STAGE listener is called inside the loop, because the object is added to the stage inside the loop. The ENTER_FRAME listener is called the next time a frame is entered, which will be after all the code in the current frame has executed. At this point i will be 10, because the loop has finished.

Here's a simplified example:

var i:int = 0;

function f() {
    trace(i);
}

f(); // output: 0
i = 2;
f(); // output: 2

In your second example, the names are created inside the loop, so i is evaluated inside the loop, and you get your expected output.

2
votes

Took me a while to find it out.

The function gets called when the event happens. Since the function is inside your loop it gets called there.

On the added to stage event it is being called when your movieclip is being added. Since that happens in the same iteration the value from i is correct.

The enterframe starts happening after the loop is done. When the function gets called the value of i is 10. Hence you always get 10.

In your second example you don't use the value of i in your function. The value of i is resolved in the name on every iteration so in the name you get the value of i when it was resolved in the loop.