A variable is declared with var and a constant with const.
Unlike ActionScript 1.0 and 2.0, the declaration is always required: assigning to a name
that was never declared is an error.
var
var name[:Type] [= value] [, name[:Type] [= value]]… ;
var i:int; // 0
var total:Number = 0.5;
var a:int = 10, b:int = 20, c:int = 30;
var list:Array = [], map:Object = {};
A variable declared without a value starts at its type’s default:
false for Boolean, 0 for int and
uint, NaN for Number, undefined
when untyped, and null for String, Object and
every class. A variable declared with var cannot be removed with
delete.
const
const NAME[:Type] = value ;
A constant is given its value once. For a local or package-level constant, and for a
static constant, that happens in the declaration. An instance constant may
instead be set in the constructor; strict mode accepts only the declaration. Changing it
anywhere else is an error. By convention constants are named in capitals with
underscores, like MouseEvent.DOUBLE_CLICK.
The constant holds a fixed reference, not a fixed object: a const
Array can still have elements pushed into it.
Where a declaration can go
| Place | What it makes | Visible to |
|---|---|---|
Inside a package block, outside any class | A package-level variable or constant; it must be the file’s single public definition, or internal | Code that imports it, or the package |
| In a class body | A property: an instance variable, or with static a class variable | Set by its access attribute; see Classes |
| In a function or method | A local variable | The whole function, and functions nested in it |
| Outside the package block of a file | A file-level variable | The rest of that file |
| In a frame script in a Flash document | A property of the timeline’s class | Every frame script on that timeline |
Function scope, not block scope
A local variable belongs to the whole function that declares it. Braces of an
if, a loop or a bare block do not make a new scope, so a variable declared
inside one can be used after it. This differs from Java and C++, and from the
let of later JavaScript, which ActionScript does not have.
function blockTest(items:Array):void {
if (items.length > 0) {
var first:String = items[0];
}
for (var i:int = 0; i < items.length; i++) {
var item:String = items[i];
}
trace(first, i, item); // all three are still in scope
}
Declaring the same name twice in one function, for instance var i in two
loops, is allowed but draws a duplicate-declaration warning (and an error when the
types differ).
Hoisting
The compiler moves every var declaration to the top of its function,
but leaves the assignment where it is. A variable can therefore be used before its
declaration line, and holds its default value until the assignment runs.
trace(num); // NaN: declared, not yet assigned
var num:Number = 10;
trace(num); // 10
Named function statements are hoisted the same way: a nested function can be called above the line that defines it.
Shadowing and the scope chain
A name is looked up through a chain of scopes, innermost first:
- the local variables and parameters of the current function;
- those of each enclosing function, for a nested function or closure;
- the members of the current object (
this), then the static members of its class and its superclasses; - the definitions of the file and its imported packages, then the global scope.
A with statement puts its object in front of the chain for the code
inside it. A local variable with the same name as a property hides the property; use
this.name to reach the property, as constructors often do:
this.width = width.
Closures
A function created inside another keeps its enclosing variables alive and sees their current values, not copies. Because there is no block scope, every function made in a loop shares the one loop variable.
var handlers:Array = [];
for (var i:int = 0; i < 3; i++) {
handlers.push(function ():void { trace(i); });
}
handlers[0](); // 3, not 0
function makeHandler(n:int):Function {
return function ():void { trace(n); };
}
for (var j:int = 0; j < 3; j++) {
handlers[j] = makeHandler(j); // each keeps its own n
}