ActionScript 3 variable scope: developers beware!

! Warning: this post hasn't been updated in over three years and so may contain out of date information.

Consider, if you will, the following piece of non-language-specific code:

If you are a C#, Java, C++ etc developer, such a piece of code might look decidedly unspectacular. Not so with ActionScript 3 (AS3) though as I recently discovered.

The equivalent in AS3 would be:

and this code won’t compile. Instead it will report an error due to variable i being redefined as a different type. Further, if you change i in the first loop to be an int too, the compiler will then issue a warning that you are redefining i.

Being used to languages such as Java, C# and C++, I put this down to a compiler bug, disabled what I thought was a pointless warning message in my projects and carried on happy I’d hidden an annoying bug. How wrong I was. I recently discovered a bug in my code was due to a variable defined inside a loop changing the value of a variable of the same name at the method-scope level. It turns out that AS3 doesn’t support block-level scope for variables. Variables can only have one of three scopes:

  • Global
  • Class
  • Function

Whilst a function-level variable can override a class-level one, variables defined inside code blocks (such as loops, try blocks etc) have method-level scope.

The following code illustrates how AS3 variable scoping works:

Tracing through the code, I would have expected the following output:

The resultant SWF is included below. The results are really rather different:

The version of aVariable defined in go() is in scope from the start of the method, so label1 picks up its default value, rather than the class-scoped variable’s value. And the loop uses the same variable, so label4 is 4, rather than 2.

For more information on AS3 variable scoping, I refer you to the “Understanding variable scope” section of Adobe’s official AS3 language reference.

You can download a zip of the FlexBuilder project used to create the above SWF here.