The scope of a variable is the area of
your code where the variable can be accessed by a lexical reference.
A global variable is one that is defined in all areas of
your code, whereas a local variable is one that is defined
in only one part of your code. In ActionScript 3.0, variables are
always assigned the scope of the function or class in which they
are declared. A global variable is a variable that you define outside
of any function or class definition. For example, the following code
creates a global variable strGlobal by declaring
it outside of any function. The example shows that a global variable
is available both inside and outside the function definition.
var strGlobal:String = "Global";
function scopeTest()
{
trace(strGlobal); // Global
}
scopeTest();
trace(strGlobal); // Global
You declare a local variable by declaring the variable inside
a function definition. The smallest area of code for which you can
define a local variable is a function definition. A local variable
declared within a function exists only in that function. For example,
if you declare a variable named str2 within a function
named localScope(), that variable is not available
outside the function.
function localScope()
{
var strLocal:String = "local";
}
localScope();
trace(strLocal); // error because strLocal is not defined globally
If the variable name you use for your local variable is already
declared as a global variable, the local definition hides (or shadows)
the global definition while the local variable is in scope. The
global variable still exists outside of the function. For example,
the following code creates a global string variable named str1, and
then creates a local variable of the same name inside the scopeTest() function.
The trace statement inside the function outputs
the local value of the variable, but the trace statement
outside the function outputs the global value of the variable.
var str1:String = "Global";
function scopeTest ()
{
var str1:String = "Local";
trace(str1); // Local
}
scopeTest();
trace(str1); // Global
ActionScript variables, unlike variables in
C++ and Java, do not have block-level scope. A block of code is
any group of statements between an opening curly bracket ({)
and a closing curly bracket (}). In some programming
languages, such as C++ and Java, variables declared inside a block
of code are not available outside that block of code. This restriction
of scope is called block-level scope, and does not exist in ActionScript.
If you declare a variable inside a block of code, that variable
is available not only in that block of code, but also in any other
parts of the function to which the code block belongs. For example,
the following function contains variables that are defined in various
block scopes. All the variables are available throughout the function.
function blockTest (testArray:Array)
{
var numElements:int = testArray.length;
if (numElements > 0)
{
var elemStr:String = "Element #";
for (var i:int = 0; i < numElements; i++)
{
var valueStr:String = i + ": " + testArray[i];
trace(elemStr + valueStr);
}
trace(elemStr, valueStr, i); // all still defined
}
trace(elemStr, valueStr, i); // all defined if numElements > 0
}
blockTest(["Earth", "Moon", "Sun"]);
An interesting implication
of the lack of block-level scope is that you can read or write to
a variable before it is declared, as long as it is declared before
the function ends. This is because of a technique called hoisting,
which means that the compiler moves all variable declarations to
the top of the function. For example, the following code compiles
even though the initial trace() function for the num variable
happens before the num variable is declared:
trace(num); // NaN
var num:Number = 10;
trace(num); // 10
The compiler will not, however, hoist any assignment statements.
This explains why the initial trace() of num results
in NaN (not a number), which is the default value
for variables of the Number data type. This means that you can assign
values to variables even before they are declared, as shown in the following
example:
num = 5;
trace(num); // 5
var num:Number = 10;
trace(num); // 10