views:

3638

answers:

3

I'm an experienced programmer but just starting out with Flash/Actionscript. I'm working on a project that for certain reasons requires me to use Actionscript 2 rather than 3.

When I run the following (I just put it in frame one of a new flash project), the output is a 3 rather than a 1 ? I need it to be a 1.

Why does the scope of the 'ii' variable continue between loops?

var fs:Array = new Array();

for (var i = 0; i < 3; i++){

    var ii = i + 1; 
    fs[i] = function(){
     trace(ii);
    }
}

fs[0]();
A: 

Unfortunately Actionscript 2.0 does not have a strong scope... especially on the time line.

var fs:Array = new Array();

for (var i = 0; i < 3; i++){

    var ii = i + 1;     
    fs[i] = function(){
        trace(ii);
    }
}

fs[0]();
trace("out of scope: " + ii + "... but still works");
gltovar
+1  A: 

Unfortunately, AS2 is not that kind of language; it doesn't have that kind of closure. Functions aren't exactly first-class citizens in AS2, and one of the results of that is that a function doesn't retain its own scope, it has to be associated with some scope when it's called (usually the same scope where the function itself is defined, unless you use a function's call or apply methods).

Then when the function is executed, the scope of variables inside it is just the scope of wherever it happened to be called - in your case, the scope outside your loop. This is also why you can do things like this:

function foo() {
    trace( this.value );
}

objA = { value:"A" };
objB = { value:"B" };

foo.apply( objA ); // A
foo.apply( objB ); // B

objA.foo = foo;
objB.foo = foo;

objA.foo(); // A
objB.foo(); // B

If you're used to true OO languages that looks very strange, and the reason is that AS2 is ultimately a prototyped language. Everything that looks object-oriented is just a coincidence. ;D

fenomas
A: 

I came up with a kind of strage solution to my own problem:

var fs:Array = new Array();

for (var i = 0; i < 3; i++){    
    var ii = i + 1;   

    f = function(j){
     return function(){
      trace(j);
     };
    };
    fs[i] = f(ii);
}

fs[0](); //1
fs[1](); //2
fs[2](); //3
Bill
This is what i what i tried to say in my reply too but for some reason the code is broken and not visible correctly
Antti