5.1. General Features of Operators
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.
5.1.1. Operators and Expressions
Operators
perform some action 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 (*). The operands can be
any kind of expression, for example:
player1score + bonusScore; // Operands are variables
(x + y) - (Math.PI * radius * radius); // Operands are complex expressions
Observe in the second example that both the left and right operands
of the - operator are expressions that themselves involve other
operations. We can use complex expressions to create even larger
expressions, such as:
((x + y) - (Math.PI * radius * radius)) / 2 // Divide the whole thing by 2
When expressions become very large, consider using variables to hold
interim results for both convenience and clarity. Remember to name
your variables descriptively, such as:
var radius = 10;
var height = 25;
var circleArea = (Math.PI * radius * radius);
var cylinderVolume = circleArea * height;
5.1.2. Number of Operands
Operators are sometimes categorized according to how
many operands they take. 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 with two operands are called
binary operators; operators with 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.
5.1.3. Operator Precedence
An operator
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 + (5 * 6) because the *
operator has higher precedence than the +
operator. When in doubt, or to ensure a different order of operation,
use parentheses, which have the highest
precedence:
(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 is greater than y or y equals z
x > y || y == 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!
Table 5-1 shows the precedence of each operator.
Operators with the highest precedence (at the top of the table) are
executed first. Operators with the same precedence are performed left
to right.
Table 5-1. ActionScript Operator Associativity and Precedence
|
Operator |
Precedence |
Associativity |
Description |
|
x++ |
16 |
left to right |
postfix increment |
|
x-- |
16 |
left to right |
postfix decrement |
|
. |
15 |
left to right |
object property access |
|
[] |
15 |
left to right |
array element access |
|
( ) |
15 |
left to right |
parentheses |
|
function( ) |
15 |
left to right |
function call |
|
++x |
14 |
right to left |
prefix increment |
|
--x |
14 |
right to left |
prefix decrement |
|
- |
14 |
right to left |
unary negation |
|
~ |
14 |
right to left |
bitwise NOT |
|
! |
14 |
right to left |
logical NOT |
|
new |
14 |
right to left |
create object/array |
|
delete |
14 |
right to left |
remove object/property/array element |
|
typeof |
14 |
right to left |
determine datatype |
|
void |
14 |
right to left |
return undefined value |
|
* |
13 |
left to right |
multiply |
|
/ |
13 |
left to right |
divide |
|
% |
13 |
left to right |
modulo division |
|
+ |
12 |
left to right |
addition or string concatenation |
|
- |
12 |
left to right |
subtraction |
|
<< |
11 |
left to right |
bitwise left shift |
|
>> |
11 |
left to right |
bitwise signed right shift |
|
>>> |
11 |
left to right |
bitwise unsigned right shift |
|
< |
10 |
left to right |
less than |
|
<= |
10 |
left to right |
less than or equal to |
|
> |
10 |
left to right |
greater than |
|
>= |
10 |
left to right |
greater than or equal to |
|
== |
9 |
left to right |
equality |
|
!= |
9 |
left to right |
not equal to |
|
& |
8 |
left to right |
bitwise AND |
|
^ |
7 |
left to right |
bitwise XOR |
|
| |
6 |
left to right |
bitwise OR |
|
&& |
5 |
left to right |
logical AND |
|
|| |
4 |
left to right |
logical OR |
|
?: |
3 |
right to left |
conditional |
|
= |
2 |
right to left |
assignment |
|
+= |
2 |
right to left |
add and reassign |
|
-= |
2 |
right to left |
subtract and reassign |
|
*= |
2 |
right to left |
multiply and reassign |
|
/= |
2 |
right to left |
divide and reassign |
|
%= |
2 |
right to left |
modulo division and reassign |
|
<<= |
2 |
right to left |
bit-shift left and reassign |
|
>>= |
2 |
right to left |
bit-shift right and reassign |
|
>>>= |
2 |
right to left |
bit-shift right (unsigned) and reassign |
|
&= |
2 |
right to left |
bitwise & and reassign |
|
^= |
2 |
right to left |
bitwise XOR and reassign |
|
|= |
2 |
right to left |
bitwise OR and reassign |
|
, |
1 |
left to right |
comma |
5.1.4. Operator Associativity
As we've just learned, 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:
a = 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:
a = (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))
Operator associativity is fairly intuitive, but if you're
getting an unexpected value from a complex expression, consult Table 5-1 or add extra parentheses. We'll note
cases in which associativity is a common source of errors throughout
the remainder of the chapter.
5.1.5. Datatypes and Operators
Some
operators accept multiple datatypes as
operands. Depending on the datatype of an operand, the effect of an
operator may change. The + operator, for example,
performs addition when used with numeric operands but concatenation
when used with string operands. If operands are of different
datatypes or of the wrong type, ActionScript will perform type
conversion according to the rules described in Chapter 3, "Data and Datatypes", which can have serious effects on your code.