I just fixed a lurking bug in my code today that was related to ActionScript's scoping rules. The bug wasn't obvious to me when I first wrote it, and took some head-scratching when I fixed it. So I thought I'd post in in case this behavior isn't obvious to anyone else eading this (say, coming from a Java background like I do, where this behavior doesn't exist).
I'll boil it down to a simpler 'puzzler' question:
What do you think this prints out?
var i:int; for (i = 0; i < 2; ++i) { var blah:Object; trace("blah = " + blah); blah = i; }
Or how about this?
for (i = 0; i < 2; ++i) { var blarg:Object = null; trace("blarg = " + blarg); blarg = i; }
(I'll put the answer at the end of this post, so that I don't blow the surprise for anyone wanting to figure it out before proceeding.)
What's going on here is that the scope of these variables (like all variables in ActionScript) is at the level of the function. That's right: even though the variable is declared inside the for()
loop, they are scoped to the overall function. There are various implications and consequences that come from this scoping rule, but the specific one we're dealing with here is that that scope is also the place where the variable receives its implicit assignment. So in the case of the first example above, blah
is assigned the default value of null
just once. When we come around to the variable declaration again, it does not get a second implicit assignment, because it's as if the variable were declared at the top of the function, since that's its scope.
Meanwhile, in the second example, blarg
is given an explicit assignment. This means that every time around our for()
loop, we assign the value of null
to blarg
, so that the variable is always initialized to that value at the point where we declare it in the code.
To my Java developer eye, these looked equivalent: an implicit assignment would happen at the same time as an explicit assignment. But now I realize that if you really want a variable to have a specific default value, assign it explicitly or suffer the possible consequences.
Moral of the Story: Always assign a default value to a variable, especially iuf the variable is declared in a loop where you expect it to have some default value.
Addendum: To test this behavior in Java, I tried to write similar code to see the results. It turns out that the code wouldn't even compile; accessing the variable (even to System.out.println() it ) without declaring an initial value for it threw a compiler error. I could swear this type of code used to work, but perhaps they tightened up their variable declaration policy since I used that approach.
Answers:
The first example prints out:
blah = null blah = 0
and the second example prints out:
blarg = null blarg = null