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