Statements and Operators: Chapter 10 - Essential ActionScript

by David Stiller, Rich Shupe, Darren Richardson, Jen deHaan

This excerpt is from Essential ActionScript. More than two years in the making, ActionScript 3.0 presents perhaps the most substantial upgrade to Flash's programming language ever. The enhancements to ActionScript's performance, feature set, ease of use, cleanliness, and sophistication are simply staggering. Revolutionary improvements abound. Essential ActionScript 3.0 is an update to Essential ActionScript 2.0, once again focusing on the core language and object-oriented programming with some coverage of the Flash Player API. Approximately half of the book focuses on the new features and functionality of ActionScript 3.0, while the rest focuses on changes between the 2 and 3 releases.

buy button

This chapter provides a reference-style overview of ActionScript's statements and operators—many of which we've already seen in this book. Rather than discussing each statement and operator in isolation, this book teaches the use of statements and operators in the context of other programming topics. Accordingly, this chapter lists many crossreferences to discussion and usage examples found elsewhere in this book. For information on operators not covered in this book, see Adobe's ActionScript Language Reference.

Statements

Statements are one kind of directive, or basic program instruction, consisting of a keyword (command name reserved for use by the ActionScript language) and, typically, a supporting expression.

Table 10-1, “ActionScript statements” lists ActionScript's statements, their syntax, and purpose.

Table 10-1. ActionScript statements

Statement

Usage

Description

break

break

Aborts a loop or switch statement. See Chapter 2, Conditionals and Loops.

case

caseexpression:
  substatements

Identifies a statement to be executed conditionally in a switch statement. See Chapter 2, Conditionals and Loops.

continue

continue;

Skips the remaining statements in the current loop and begins the next iteration at the top of the loop. See Adobe documentation.

default

default:substatements

Identifies the statement(s) to execute in a switch statement when the test expression does not match any case clauses. See Chapter 2, Conditionals and Loops.

do-while

do {substatements
} while (expression);

A variation of a while loop that ensures at least one iteration of the loop is performed. See Chapter 2, Conditionals and Loops.

for

for (init; test; update) {
  statements
}

Executes a statement block repetitively (a for loop). It is synonymous with a while loop but places the loop initialization and update statements together with the test expression at the top of the loop. See Chapter 2, Conditionals and Loops.

for-in

for (variable in object) {
   statements
}

Enumerates the names of the dynamic instance variables of an object or an array's elements. See Chapter 15, Dynamic ActionScript.

for-each-in

for each
(variableOrElementValue in
object) {
  statements
}

Enumerates the values of an object's dynamic instance variables or an array's elements. See Chapter 15, Dynamic ActionScript.

if-else if-else

if (expression) {
   substatements
} else if (expression) {
   substatements
} else {
   substatements
}

Executes one or more statements, based on a condition or a series of conditions. See Chapter 2, Conditionals and Loops.

label

label: statement
label: statements

Associates a statement with an identifier. Used with break or continue. See Adobe documentation.

return

return;
returnexpression;

Exits and optionally returns a value from a function. See Chapter 5, Functions.

super

super(arg1, arg2, ...argn)
super.method(arg1, arg2, ...argn)

Invokes a superclass's constructor method or overridden instance method. See Chapter 6, Inheritance.

switch

switch (expression) {
  substatements
}

Executes specified code, based on a condition or a series of conditions (alternative to if-else if-else). See Chapter 2, Conditionals and Loops.

throw

throwexpression

Issues a runtime exception (error). See Chapter 13, Exceptions and Error Handling.

try/catch/finally

try {
  // Code that might
  // generate an exception
} catch (error:ErrorType1) {
  // Error-handling code
  // for ErrorType1.
} catch (error:ErrorTypeN) {
  // Error-handling code
  // for ErrorTypeN.
} finally {
  // Code that always executes
}

Wraps a block of code to respond to potential runtime exceptions. See Chapter 13, Exceptions and Error Handling.

while

while (expression) {
   substatements
}

Executes a statement block repetitively (a while loop). See Chapter 2, Conditionals and Loops.

with

with (object) {
   substatements
}

Executes a statement block in the scope of a given object. See Chapter 16, Scope.


Operators

An operator is a symbol or keyword that manipulates, combines, or transforms data. For example, the following code uses the multiplication operator (*) to multiply 5 times 6:

5 * 6;

Though each operator has its own specialized task, all operators share a number of general characteristics. Before we consider the operators individually, let's see how they behave generally.

Operators perform actions using the data values (operands) supplied. For example, in the operation 5 * 6, the numbers 5 and 6 are the operands of the multiplication operator (*).

Operations can be combined to form complex expressions. For example:

((width * height) - (Math.PI * radius * radius)) / 2

When expressions become very large, consider using variables to hold interim results for both convenience and clarity. Remember to name your variables descriptively. For example, the following code has the same result as the preceding expression but is much easier to read:

var radius:int = 10;
var height:int = 25;
var circleArea:Number = (Math.PI * radius * radius);
var cylinderVolume:Number = circleArea * height;

Number of Operands

Operators are sometimes categorized according to how many operands they take (i.e., require or operate on). Some ActionScript operators take one operand, some take two, and one even takes three:

-x                                         // One operand
x * y                                      // Two operands
(x == y) ? "true result" : "false result"  // Three operands

Single-operand operators are called unary operators; operators that take two operands are called binary operators; operators that take three operands are called ternary operators. For our purposes, we'll look at operators according to what they do, not the number of operands they take.

Operator Precedence

Operators' precedence determines which operation is performed first in an expression with multiple operators. For example, when multiplication and addition occur in the same expression, multiplication is performed first:

4 + 5 * 6  // Yields 34, because 4 + 30 = 34

The expression 4 + 5 * 6 is evaluated as "4 plus the product of 5 * 6" because the * operator has higher precedence than the + operator.

Similarly, when the less-than (<) and concatenation (+) operators occur in the same expression, concatenation is performed first. For example, suppose we want to compare two strings and then display the result of that comparison during debugging. Without knowing the precedence of the < and + operators, we might mistakenly use the following code:

trace("result: " + "a" < "b");

Due precedence of the < and + operators, the preceding code yields the value:

false

whereas we were expecting it to yield:

result: true

To determine the result of the expression "result: " + "a" < "b", ActionScript performs the concatenation operation first (because + has a higher precedence than <). The result of concatenating "result:" with "a" is a new string, "result: a". ActionScript then compares that new string with "b", which yields false because the first character in "result: a" is alphabetically greater than "b".

When in doubt, or to ensure a different order of operation, use parentheses, which have the highest precedence:

"result: " + ("a" < "b")  // Yields: "result: true"
(4 + 5) * 6               // Yields 54, because 9 * 6 = 54

Even if not strictly necessary, parentheses can make a complicated expression more readable. The expression:

x > y || y == z  // x is greater than y, or y equals z

may be difficult to comprehend without consulting a precedence table. It's a lot easier to read with parentheses added:

(x > y) || (y == z)  // Much better!

The precedence of each operator is listed later in Table 10-2, “ActionScript operators”.

Operator Associativity

As we've just seen, operator precedence indicates the pecking order of operators: those with a higher precedence are executed before those with a lower precedence. But what happens when multiple operators occur together and have the same level of precedence? In such a case, we apply the rules of operator associativity, which indicate the direction of an operation. Operators are either left-associative (performed left to right) or right-associative (performed right to left). For example, consider this expression:

b * c / d

The * and / operators are left-associative, so the * operation on the left (b * c) is performed first. The preceding example is equivalent to:

(b * c) / d

In contrast, the = (assignment) operator is right-associative, so the expression:

a = b = c = d

says, "assign d to c, then assign c to b, then assign b to a," as in:

a = (b = (c = d))

Unary operators are right-associative; binary operators are left-associative, except for the assignment operators, which are right-associative. The conditional operator (?:) is also right-associative. Operator associativity is fairly intuitive, but if you're getting an unexpected value from a complex expression, add extra parentheses to force the desired order of operations. For further information on operator associativity in ActionScript, see Adobe's documentation.

Datatypes and Operators

The operands of most operators are typed. In strict mode, if a value used for an operand does not match that operand's datatype, the compiler generates a compile-time error and refuses to compile the code. In standard mode, the code compiles, and at runtime, if the operand's type is a primitive type, ActionScript converts the value to the operand's datatype (according to the rules described in Chapter 8, Datatypes and Type Checking, in the section "the section called “Conversion to Primitive Types”"). If the operand's type is not a primitive type, ActionScript generates a runtime error.

For example, in strict mode, the following code causes a type mismatch error because the datatype of the division (/) operator's operands is Number, and the value "50" does not belong to the Number datatype:

"50" / 10

In standard mode, the preceding code does not cause a compile-time error. Instead, at runtime, ActionScript converts the String value "50" to the Number datatype, yielding 50, and the entire expression has the value 5.

To compile the preceding code without causing an error in strict mode, we must cast the String value to the required datatype, as follows:

Number("50") / 10

Some operators' operands are untyped, which allows the result of the operation to be determined at runtime based on the datatypes of the supplied values. The + operator, for example, performs addition when used with two numeric operands, but it performs concatenation when either operand is a string.

The datatypes of each operator's operands are listed in Adobe's ActionScript Language Reference.

Operator Overview

Table 10-2, “ActionScript operators” lists ActionScript's operators, their precedence value, a brief description, and a typical example of their use. Operators with the highest precedence (at the top of the table) are executed first. Operators with the same precedence are performed in the order they appear in the expression, usually from left to right, unless the associativity is right to left.

Note that with the exception of the E4X operators, this book does not provide exhaustive reference information for ActionScript's operators. For details on a specific operator, consult Adobe's ActionScript Language Reference. For information on the bitwise operators, see the article "Using Bitwise Operators in ActionScript" at http://www.moock.org/asdg/technotes/bitwise.

Table 10-2. ActionScript operators

Operator

Precedence

Description

Example

.

15

Multiple uses:

  • Accesses a variable or method

  • Separates package names from class names and other package names

  • Accesses children of an XML or XMLList object (E4X)

// Access a variable
product.price
// Reference a class
flash.display.Sprite
// Access an XML child element
novel.TITLE

[]

15

Multiple uses:

  • Initializes an array

  • Accesses an array element

  • Accesses a variable or method using any expression that yields a string

  • Accesses children or attributes of an XML or XMLList object (E4X)

// Initialize an array
["apple", "orange", "pear"]
// Access fourth element of an array
list[3]
// Access a variable
product["price"]
// Access an XML child element
novel["TITLE"]

( )

15

Multiple uses:

  • Specifies a custom order of operations (precedence)

  • Invokes a function or method

  • Contains an E4X filtering predicate

// Force addition before multiplication
(5 + 4) * 2
// Invoke a function
trace( )
// Filter an XMLList
staff.*.(SALARY <= 35000)

@

15

Accesses XML attributes

// Retrieve all attributes of novel
novel.@*

::

15

Separates a qualifier namespace from a name

// Qualify orange with namespace fruit
fruit::orange

..

15

Accesses XML descendants

// Retrieve all descendant elements
// of loan named DIRECTOR
loan..DIRECTOR

{x:y}

15

Creates a new object and initializes its dynamic variables

// Create an object with dynamic variables,
// width and height
{width:30, height:5}

new

15

Creates an instance of a class

// Create TextField instance
new TextField( )

<tag> <tag/>

15

Defines an XML element

// Create an XML element named BOOK
<BOOK>Essential ActionScript 3.0</BOOK>

x++

14

Adds one to x and returns x's former value (postfix increment)

// Increase i by 1, and return i
i++

x--

14

Subtracts one from x and returns x's former value (postfix decrement)

// Decrease i by 1, and return i
i--

++ x

14

Adds one to x and returns x's new value (prefix increment)

// Increase i by 1, and return the result
++i

-- x

14

Subtracts one from x and returns x's new value (prefix decrement)

// Decrease i by 1, and return the result
--i

-

14

Switches the operand's sign (positive becomes negative, and negative becomes positive)

var a:int = 10;
// Assign −10 to b
var b:int = -b;

~

14

Performs a bitwise NOT

// Clear bit 2 of options
options &= ~4;

!

14

Returns the Boolean opposite of its single operand

// If under18's value is not true,
// execute conditional body
if (!under18) {
  trace("You can apply for a credit card")
}

delete

14

Multiple uses:

  • Removes the value of an array element

  • Removes an object's dynamic instance variable

  • Removes an XML element or attribute

// Create an array
var genders:Array = ["male","female"]
// Remove the first element's value
delete genders[0];
// Create an object
var o:Object = new Object( );
o.a = 10;
// Remove dynamic instance variable a
delete o.a;
// Remove the <TITLE> element from the XML
// object referenced by novel
delete novel.TITLE;

typeof

14

Returns a simple string description of various types of objects. Used for backwards compatibility with ActionScript 1.0 and ActionScript 2.0 only.

// Retrieve string description of 35's type
typeof 35

void

14

Returns the value undefined

var o:Object = new Object( );
o.a = 10;
// Compare undefined to the value of o.a
if (o.a == void) {
  trace("o.a does not exist, or has no value");
}

*

13

Multiplies two numbers

// Calculate four times six
4 * 6

/

13

Divides left operand by right operand

// Calculate 30 divided by 5
30 / 5

%

13

Returns the remainder (i.e., modulus) that results when the left operand is divided by the right operand

// Calculate remainder of 14 divided by 4
14 % 4

+

12

Multiple uses:

  • Adds two numbers

  • Combines(concatenate) two strings

  • Combines (concatenate) two XML or XMLList objects

// Calculate 25 plus 10
25 + 10
// Combine "He" and "llo" to form "Hello"
"He" + "llo"
// Combine two XML objects
<JOB>Programmer</JOB> + <AGE>52</AGE>

-

12

Subtracts right operand from left operand

// Subtract 2 from 12
12 - 2

<<

11

Performs a bitwise left shift

// Shift 9 four bits to the left
9 << 4

>>

11

Performs a bitwise signed right shift

// Shift 8 one bit to the right
8 >> 1

>>>

11

Performs a bitwise unsigned right shift

// Shift 8 one bit to the right, filling
// vacated bits with zeros
8 >>> 1

<

10

Checks if the left operand is less than the right operand. Depending upon the evaluation of the operands, returns true or false.

// Check if 5 is less than 6
5 < 6
// Check if "a" has a lower character code point
// than "z"
"a" < "z"

<=

10

Checks if the left operand is less than or equal to the right operand. Depending on the evaluation of the operands, returns true or false.

// Check if 10 is less than or equal to 5
10 <= 5
// Check if "C" has a lower character code point
// than "D", or the same code point as "D"
"C" <= "D"

>

10

Checks if the left operand is greater than the right operand. Depending upon the evaluation of the operands, returns true or false.

// Check if 5 is greater than 6
5 > 6
// Check if "a" has a higher character code point
// than "z"
"a" > "z"

>=

10

Checks if the left operand is greater than or equal to the right operand. Depending on the evaluation of the operands, returns true or false.

// Check if 10 is greater than or equal to 5
10 >= 5
// Check if "C" has a higher character code point
// than "D", or the same code point as "D"
"C" >= "D"

as

 

Checks if the left operand belongs to the datatype specified by the right operand. If yes, returns the object; otherwise returns null

var d:Date = new Date( )
// Check if d's value belongs to
// the Date datatype
d as Date

is

 

Checks if the left operand belongs to the datatype specified by the right operand. If yes, returns the true; otherwise returns false.

var a:Array = new Array( )
// Check if a's value belongs to
// the Array datatype
a is Array

in

 

Checks if an object has a specified public instance variable or public instance method. Depending on the evaluation of the operands, returns true or false.

var d:Date = new Date( )
// Check if d's value has a public variable or
// public method named getMonth
"getMonth" in d

instanceof

10

Checks if the left operand's prototype chain includes the right operand. Depending on the evaluation of the operands, returns true or false.

var s:Sprite = new Sprite( )
// Check if s's value's prototype chain
// includes DisplayObject
s instanceof DisplayObject

==

9

Checks whether two expressions are considered equal (equality). Depending on the evaluation of the operands, returns true or false.

// Check whether the expression "hi" is equal to
// the expression "hello"
"hi" == "hello"

!=

9

Checks whether two expressions are considered not equal (in equality). Depending upon the evaluation of the operands, returns true or false.

// Check whether the expression 3 is not equal to
// the expression 3
3 != 3

===

9

Checks whether two expressions are considered equal without datatype conversion for primitive types (strict equality). Depending on the evaluation of the operands, returns true or false.

// Check whether the expression "3" is equal to
// the expression 3. This code compiles in
// standard mode only.
"3" === 3

!==

9

Checks whether two expressions are considered not equal without datatype conversion for primitive types (strict equality). Depending on the evaluation of the expression, returns true or false.

// Check whether the expression "3" is not equal to
// the expression 3. This code compiles in
// standard mode only.
"3" === 3

&

8

Performs a bitwise AND

// Combine bits of 15 and 4 using bitwise AND
15 & 4

^

7

Performs a bitwise XOR

// Combine bits of 15 and 4 using bitwise XOR
15 ^ 4

|

6

Performs a bitwise OR

// Combine bits of 15 and 4 using bitwise OR
15 | 4

&&

5

Compares two expressions using a logical AND operation. If the left operand is false or converts to false, && returns the left operand; otherwise && returns the right operand.

var validUser:Boolean = true;
var validPassword:Boolean = false;
// Check if both validUser and validPassword
// are true
if (validUser || validPassword) {
  // Do login...
}

||

4

Compares two expressions using a logical OR operation. If the left operand is true or converts to true, || returns the left operand; otherwise || returns the right operand.

var promotionalDay:Boolean = false;
var registeredUser:Boolean = false;
// Check if either promotionalDay or registeredUser
// is true
if (promotionalDay || registeredUser) {
  // Show premium content...
}

?:

3

Performs a simple conditional. If the first operand is true or converts to true, the value of the second operand is evaluated and returned. Otherwise, the value of the third operand is evaluated and returned.

// Invoke one of two methods based on
// whether soundMuted is true
soundMuted ? displayVisualAlarm() : playAudioAlarm( )

=

2

Assigns a value to a variable or array element

// Assign 36 to variable age
var age:int = 36;
// Assign a new array to variable seasons
var seasons:Array = new Array( );
// Assign "winter" to first element of seasons
seasons[0] = "winter";

+=

2

Adds (or concatenates) and reassigns

// Add 10 to n's value
n += 10; // same as n = n + 10;
// Add an exclamation mark to the end of msg
msg += "!"
// Add an <AUTHOR> tag after the first <AUTHOR>
// tag child of novel
novel.AUTHOR[0] += <AUTHOR>Dave Luxton</AUTHOR>;

-=

2

Subtracts and reassigns

// Subtract 10 from n's value
n -= 10; // same as n = n - 10;

*=

2

Multiplies and reassigns

// Multiply n's value by 10
n *= 10; // same as n = n * 10;

/=

2

Divides and reassigns

// Divide n's value by 10
n /= 10; // same as n = n / 10;

%=

2

Performs modulo division and reassigns

// Assign n%4 to n
n %= 4; // same as n = n % 4;

<<=

2

Shifts bits left and reassigns

// Shift n's bits two places to the left
n <<= 2; // same as n = n << 2;

>>=

2

Shifts bits right and reassigns

// Shift n's bits two places to the right
n >>= 2; // same as n = n >> 2;

>>>=

2

Shifts bits right (unsigned) and reassigns

// Shift n's bits two places to the right, filling
// vacated bits with zeros
n >>>= 2; // same as n = n >>> 2;

&=

2

Performs bitwise AND and reassigns

// Combine n's bits with 4 using bitwise AND
n &= 4 // same as n = n & 4;

^=

2

Performs bitwise XOR and reassigns

// Combine n's bits with 4 using bitwise XOR
n ^= 4 // same as n = n ^ 4;

|=

2

Performs bitwise OR and reassigns

// Combine n's bits with 4 using bitwise OR
n |= 4 // same as n = n | 4;

,

1

Evaluates left operand, then right operand

// Initialize and increment two loop counters
for (var i:int = 0, j:int = 10; i < 5; i++, j++) {
  // i counts from 0 through 4
  // j counts from 10 through 14
}

Up Next: Managing Lists of Information

This chapter covered some of ActionScript's basic built-in programming tools. In the next chapter, we'll study another essential ActionScript tool: arrays. Arrays are used to manage lists of information.