6.3.1
Loops
and Conditionals
We've already had several informal encounters with loops and conditionals. Together, these two statement types account for the majority of complex flow in our programs. Loops allow us to execute statement blocks repeatedly, and conditionals allow us to execute statement blocks under only the specified circumstances. See Chapter 7 and Chapter 8 for complete details.
6.3.2 Expression Statements
Although any expression can be used independently as a valid statement, if the expression
performs
no action and we don't do anything with the result, the exercise is rather pointless:
"hi there"; // This doesn't do much
345 + 5; // Neither does this
Some expressions, however, have side effects that change the state of a system through variable or property assignments or by physically altering the Flash environment. In this example, an expression changes the value of
x
:
x = 345 + 5; // Much more useful
Function calls are the most powerful type of expression statement. Even if a function doesn't return a useful value, it may have a very useful side effect. For example,
gotoAndStop( )
returns the value
undefined
but has an important side effect—it moves the playhead to another frame:
gotoAndStop(5); // The value of
_currentframe
is changed to 5.
We'll learn more about function calls in Chapter 9 under "Running Functions."
6.3.3 The var Statement
The
var
statement declares a new variable:
var x;
You can assign the new variable's initial value as part of a
var
statement:
var x = 10;
When used outside a function, the
var
statement creates a variable scoped to the timeline containing the statement. When used inside a function, the
var
statement creates a variable local to that function (i.e., one that dies when the function finishes). Refer back to Chapter 2 for more information on
variables
.
6.3.4 The set Statement (Set Variable)
For most variable assignments, we use an assignment expression in statement form, like this:
x = 30;
This kind of expression, however, requires us to know the name of our variable in advance. If we want to generate the name of a variable dynamically during an assignment, we can use the
set
statement, which has the following syntax:
set(
variable
,
expression
);
where
variable
is a string expression to be used as the variable name in the assignment and
expression
is the new value to assign to it. For example:
var x;
set("x", 10); //
x
is now 10
var firstName;
set("first" + "Name", "jane"); //
firstName
is now "jane"
In the following, trickier example,
y
is not set in the
set
statement. Instead,
y
's value (
"x"
) is retrieved and that value is used as the name of the variable to set:
// Pay close attention to this one...
var y = "x";
var x;
set(y, 15); //
x
is now 15,
y
is still "x".
In Flash 4,
set
was called
Set Variable
, and it was often used to dynamically assign variables that had programmatically generated sequential
names
. It allowed programmers to simulate arrays, which were not a native part of Flash 4 ActionScript. Since arrays were added in Flash 5,
set
is rarely used anymore. In most cases, a variable can be referenced dynamically with the object property access operator,
[ ]
. For example,
// Set the value of
firstName
in the
form_mc
movie clip.
form_mc["first" + "Name"] = "jane";
// Set the value of
firstName
in the current movie clip.
this["first" + "Name"] = "jane";
However,
set
is required when dynamically referring to a local variable in a function (because local variables are not properties of any exposed ActionScript object).
6.3.5 The function Statement
Just as the
var
statement is used to
declare
(i.e., create) variables, the
function
statement is used to declare functions. The
function
statement has the following syntax:
function
funcName
(
param1
,
param2
,
param3
,...
paramn
) {
statements
}
The keyword
function
begins the statement;
funcName
is the name of the function being declared;
param1
through
paramn
define the parameters required by the function when it executes (parameters are separated by commas);
statements
is a list of one or more statements that will be executed when the function is called.
The
function
statement declares a function for later use but does not execute that function. To execute a function, we use the function's name in a
function call
statement, which we'll discuss next.
6.3.6 Function Call Statements
A function call statement executes a built-in or
user
-defined function simply by using the function's name and providing the inputs that the function needs to perform its job. The terms
call
,
run
, and
invoke
are often used interchangeably to mean that a function's name has been used to cause it to execute. Function call statements have the following general syntax:
funcName
(
arg1
,
arg2
, ...
argn
);
where
funcName
is the name of the function we want to execute and
arg1
through
argn
is the list of
arguments
(i.e., input values) that the function expects when it runs.
The function call statement is an extremely powerful and fundamental device; it's our primary means of controlling Flash movies. When we want to manipulate a movie in some way, we often call a function. Here are a few examples:
play(); // Plays the current movie
gotoAndStop(5); // Sends the playhead to frame 5
startDrag("crosshair", true); // Makes the "crosshair" instance follow
// the mouse pointer
Function calls are also used with objects to invoke
methods
:
circle.getArea();
today.getDate();
Because movie clip instances are objects, we frequently use method invocation in our scripts:
ball_mc.play()
intro_mc.gotoAndStop("end");
We'll cover the use of functions in Chapter 9, and in Chapter 12 we'll see how functions can become object methods.
6.3.7 The return Statement
When we call a function, we can optionally pass it one or more values (
parameters
or
arguments
) to manipulate during execution. Likewise, a function can send us back a
return value
(a value that results from the execution of a function and is sent back to the caller). Within the body of a function, we use the
return
statement to conclude the function's execution and optionally return a value. A
return
statement takes one of the following forms:
return;
return
expression
;
The optional
expression
, if included, becomes the return value of the function. A
return
statement without a return value exits the function and returns the value
undefined
. All
return
statements exit the current function. Note that
return
statements are not required in functions; a function without a
return
statement simply ends after the last statement in the function body and implicitly returns
undefined
. See Chapter 9 for more details on creating, calling, and terminating functions.
6.3.8 The with Statement
The
with
statement provides a shorthand way to refer to properties of an object without having to retype the object's name repeatedly. A
with
statement takes the general form:
with (
object
) {
statements
}
When a property is referenced within a
with
statement block,
object
is checked for the specified property. In other words,
with
temporarily adds
object
to the end of the scope chain for the currently executing code. If the property exists in
object
, then
object
's property is used to resolve the property reference. If the property does not exist in
object
, the remainder of the current scope chain is consulted for the property in question, as described in Chapter 2.
The following example shows the difference between executing a statement inside a
with
statement and outside a
with
statement:
PI = 10; // Set a timeline variable,
PI
with (Math) { // Execute statements in the context of
Math
trace("pi is: " + PI); // Displays: 3.1459... (
PI
is a property of
Math
)
}
trace("PI is: " + PI); // Displays: 10 (
Math
is no longer accessed)
In addition to providing
convenient
access to object properties,
with
can be used to invoke object methods:
x = 10;
y = 11;
with (Math) {
larger = max(x, y);
}
trace(larger); // Displays: 11
It is not possible to define a new property on an object that is the target of a
with
statement. For example, in the
preceding
code, the variable
larger
does not exist on the
Math
object, so the property assignment creates a new variable on the timeline that contains the
with
statement (not on
Math
!). The following code shows a misguided attempt to set a variable in
theClip_mc
:
with (theClip_mc) {
var x = 10; //
x
is set on the current timeline, not
theClip_mc
}
We can, however, legitimately use
with
to affect movie clip instances in other ways. It can provide a handy way to work with deeply nested instance structures. For example, we can change this:
this.player_mc.eyes_mc.blinkRate = 30;
this.player_mc.eyes_mc.gotoAndStop("eyesOpen");
to this:
with (this.player_mc.eyes_mc) {
blinkRate = 30; // Resets an existing variable in
eyes_mc
instance
gotoAndStop("eyesOpen"); // Function applied to
eyes_mc
instance
}
But
with
is not our only means of achieving this convenience. We can also simply assign our instance to a variable and use that variable in our references:
var eyes = this.player_mc.eyes_mc;
eyes.blinkRate = 30;
eyes.gotoAndStop("eyesOpen");
Many developers find the variable approach easier to read and work with than the
with
statement, but both are valid. We'll learn more about
treating
movie clips as objects in Chapter 13.
Note that inside a
with
statement, the value of the
this
keyword does not change; it retains the value it had outside the
with
statement. For example:
// Place the following code on _level0
// On _level0, create a
ball
object with a
radius
property
_level0.ball = { radius: 20 };
// Check the value of
'this'
outside of the
with
statement
trace(this); // Displays: _level0
// Start our
with
statement
with (_level0.ball) {
// Check the value of
'this'
inside the
with
statement
trace(this); // Still displays: _level0 (not
ball
!)
// Check the
radius
of the
ball
object
trace(radius); // Displays: 20
}
6.3.9 The ifFrameLoaded Statement
The deprecated
ifFrameLoaded
statement executes its substatements only if the specified frame has been loaded. Here's the syntax:
ifFrameLoaded (
frame_expression
) {
statements
}
where
frame_expression
must be either the number of a frame or a string indicating a frame label. If the frame indicated by
frame_expression
has downloaded to the Player,
statements
are executed; if not, the statement block is
skipped
.
Because
ifFrameLoaded
lacks an
else
clause, it was deprecated in Flash 4. In Flash 4 and later, you should use the
_totalframes
and
_framesloaded
properties with
if-else
statements to create a more versatile preloader. For example:
if (_totalframes > 0 && _framesloaded = = _totalframes) {
gotoAndPlay("beginMovie");
} else {
gotoAndPlay(_currentframe - 1);
}
6.3.10 The Empty Statement
For the sake of completeness, we should mention that it is legal to issue a statement with no content using a lone semicolon:
;
The
empty statement
has very little practical application, except that it can be used as a placeholder
anywhere
a statement is normally expected. It is not needed if you simply want to add blank lines to your code. ActionScript ignores blank vertical lines, which can be used to improve code readability.
In Flash's Normal Mode, the lone semicolon appears when the
evaluate
Action is added to a block of code. An arbitrary statement can then be added by typing into the Expression field of the Parameters panel.