Anda di halaman 1dari 77

Action Script 3

Collected By Abdullah Khamis


Abdullahone2005@yahoo.com

This Document collected from http://Ntt.cc


Beginning ActionScript 3.0 – Operators 1
Primary operators

The operators in this group is mainly used for creating Array and Object literals, grouping expressions,
calling functions, instantiating class instances, and accessing properties.

1. [ ] Initializes an array
2.
3. {x:y} Initializes an object
4.
5. () Groups expressions
6.
7. f(x) Calls a function
8.
9. new Calls a constructor
10.
11. x.y Accesses a property
12.
13. x[y] Accesses a property
14.
15. <></> Initializes an XMLList object (E4X)
16.
17. @ Accesses an attribute (E4X)
18.
19. :: Qualifies a name (E4X)
20.
21. .. Accesses a descendant XML element (E4X)

Note: ActionScript 3.0 is completely conforming implementation of the ECMAScript fourth edition draft
specification. And E4X is short for ECMAScript for XML, is a programming language extension that adds
native XML support to ECMAScript.

Because we would meet these primary operators later, I don’t show you any example code here.

Postfix operators

Only two operators in this group, one for increment, while the other one for decrement.

1. ++ Increments (postfix)
2. – Decrements (postfix)

See the following code.

Unary operators

Please notice that there are two similar operators as the postfix operators, they’re prefix increment operator
(++) and prefix decrement operator (–). And the operators in this group only need one operand.

1. ++ Increments (prefix)
2.
3. – Decrements (prefix)
4.
5. + Unary +
6.
7. - Unary - (negation)
8.
9. ! Logical NOT
10.
11. ~ Bitwise NOT
12.
13. delete Deletes a property
14.
15. typeof Returns type information
16.
17. void Returns undefined value

The difference between prefix and postfix increment/decrement.

Take a look at the following code.

1. var a:int = 2;
2. var b:int = 2;
3. var c:int;
4. var d:int;
5.
6. c = a++;
7. d = ++b;
8. trace(c);
9. trace(d);

If you run the code, you will find that the value of c is 2, and the value of d is 3.

What cause this difference? Actually, it’s because the sequence of increment /decrement and assignment.
The prefix operator do the increment or decrement operation first then return its value, while the postfix
return the value first then do the increment or decrement operation. And this is the difference between prefix
operator and postfix operator.

So, be careful when you mix the assignment and postfix/prefix operator.

Multiplicative operators

The operators in this group are very common.

1. * Multiplication
2.
3. / Division
4.
5. % Modulo

Modulo operator is very useful when you want to map a big range into a smaller range.

For example, we may use 1-52 represent the four suit cards, maybe 1-13 is for the diamond, 14-26 for the
club and so on. You know the corresponding card to each number, but others don’t. So, it’s necessary to
map the integer to the corresponding card.

1. var type:int = (someNumber - 1) / suitNumber;


2. var cardNumber:int = (someNumber - 1) % suitNumber + 1;

Here, suppose the input is someNumber, and the type describes the input number’s corresponding card
type, and the cardNumber is the card’s value. If you interested in it, see the full code in ending of this article.

Additive operators
Here the ―-―is binary operator,

1. + Addition
2. - Subtraction

The addition operator not only use in arithmetic operation, but also use in joining the strings.

So, when the addition operator meets different type operands, its behavior seems to be different. When the
addition operator meets two integers, it returns the result of two operand’s addition; when the addition
operator meets two strings, it joins the two strings together. This is called overload.

Overload is an important concept in some other programming language, especially the languages support
Object-Oriented, such as C++ and Java, but not so important in ActionScript, since ActionScript 3.0 doesn’t
support this mechanism semantically. And overload is often appearing with functions, it means you can use
the same function name to deal with different parameters, and the behavior will be also be different. And
different parameters mean the type or the number, or both.

Now, you just need to know overload is a mechanism that when the operator meets different operands, its
behavior might get changed.

1. ===Mapping the numbers to corresponding card.===========


2.
3. const suitNumber:int = 13;
4.
5. for(var i:int = 1; i <= 52; i++)
6. {
7. printCard(i);
8. }
9.
10. function printCard(someNumber:int):void
11. {
12. var msg:String = ―‖;
13. var type:int = (someNumber - 1) / suitNumber;
14. var cardNumber:int = (someNumber - 1) % suitNumber + 1;
15.
16. switch(type){
17. case 0:
18. msg += ―diamond ―;
19. break;
20.
21. case 1:
22. msg += ―club ―;
23. break;
24.
25. case 2:
26. msg += ―heart ―;
27. break;
28.
29. case 3:
30. msg += ―spade ―;
31. break;
32.
33. default:
34. break;
35. }
36.
37. switch(cardNumber) {
38. case 1:
39. msg += ―A‖;
40. break;
41.
42. case 11:
43. msg += ―J‖;
44. break;
45.
46. case 12:
47. msg += ―Q‖;
48. break;
49.
50. case 13:
51. msg += ―K‖;
52. break;
53.
54. default:
55. msg += cardNumber.toString();
56. break;
57. }
58.
59. trace(msg);
60. }

Beginning ActionScript 3.0 – Operators 2


Bitwise operation

As you know, the computer is base on binary system. And in many programming languages, they use 2’s
complement code to store the integer values, such as C/C++, Java, or ActionScript.

Now, suppose we use 8-bit to store the integer with 2’s complement code. In this way, the 1, 2 and 4’s
representations will be as follows.

Note: just focus on the lower 8-bit and this situation in 8-bit is just the same as 32-bit, when they use the
same representation.

What can you get from the above image, from 1 to 2, from 2 to 4 or from 1 to 4?

Actually, you just need to shift the bits. Take the 1 to 2 as an example; you just need to shift all the bits of 1
left by one bit offset, it means that the ―0000 0001‖ (1) will changed into ―0000 0010‖ (2), discard the left-
most bit (It should be most significant bit exactly) and 0 fill in on the right. And if you shift all the bits of 1 left
by two bits offset, it will changes to ―0000 0100‖, which means 4 in 2’s complement code.
Here are some basic equations.

1. 2 = 1 * 2^1;
2. 4 = 1 * 2^2;

Maybe you get something from the equations. Aha, the equation can be rewrite into:

1. Result = some value * 2 ^ offset.

When the current value is 1, you need to shift 1-bit offset, eh, to the left, then you can get 2, and shift 2-bit
offset, you can get 4. Remember the direction you shift the bits is very important.

This is an operation called bitwise shift. To be exactly, the operation we introduced above is bitwise left shift.
Besides bitwise left shift, there are bitwise right shift and bitwise unsigned right shift in ActionScript 3.0.

Bitwise shift operators

In ActionScript, the bitwise shift operators take two operands and shift the bits of the first operand to the
extent specified by the second operand.

1. << Bitwise left shift


2. >> Bitwise right shift
3. >>> Bitwise unsigned right shift

So, in ActionScript, if you want to get 4 by shifting 1, you can write the following code:

1. var i:int = 1;
2. var k:int = i << 2;

Just like:

1. result = some value << offset.


Shift left, you can quickly get the result if you want to multiply some value with 2^n; correspondingly, if you
want to divide some value by 2^n, you can use shift right.

1. Result = some value << offset = some value / 2^offset

Besides left shift and right shift, there is an unsigned right shift. What’s the difference between right shift and
unsigned right shift?

Code says louder.

See the difference. This tells us that the unsigned right shift is use for unsigned integers, but not for signed
integers. The actual mechanism is too boring for you. So I don’t want to write it down. You just need to
remember the followings:

1. Result = some value << offset = some value * 2^offset


2. Result = some value << offset = some value / 2^offset

And don’t use unsigned right shift for signed integers, especially negative values.

Eh, I want to tell you one more thing here.

Try to run the following code first.

1. var i:int = 1;
2. var j:int = i << 100;
3.
4. trace(j);

Then, tell me the value of j.

OK, do you think it will be 0? Actually, it was 16 in my computer, if you get another result, please tell me.

The answer is:

1. var j:int = i << (100%32);

So, you won’t get 0, but 16, because the compiler cheats you This situation is very common in other
programming languages, so, be careful.

When you need to do some value operations concern with 2 or the power of 2, bitwise shift operators may
be useful. Yeah, it’s ―may‖ not ―surely‖, because some compilers will optimized your code automatically. So,
if you don’t want to use the bitwise operators, just don’t use them. And too much bitwise operations may
bring down readability of your code.

Beginning ActionScript 3.0 – Operators 3


Today, we’re going to talk about the relational operators, equality operators and bitwise logical operators.

Relational operators

When we introduce the associativity, we use the following example:

1. trace(3 > 2 < 1);


2. trace ((3 > 2) < 1 );
3. trace (3 > (2 < 1) );

Here, the > operator and < operator are relational operators. The relational operators take two operands,
compare their values, and return a Boolean value. All the relational operators are as below.

1. < Less than


2. > Greater than
3. <= Less than or equal to
4. >= Greater than or equal to
5. as Checks data type
6. in Checks for object properties
7. instanceof Checks prototype chain
8. is Checks data type
instanceof Checks prototype chain

is Checks data type

You should familiar the first four relational operators. When you use these operators to perform integer
values’ comparison, they work as you learn in mathematics.

When we talk about the + operator, we mention a mechanism called overload. This mechanism also works
for these four relational operators. You can use these operators to compare the string values. And this is
very common operation in our daily programming.

Let’s declare some string variables first.

1. var i:String = ―hello‖;


2. var j:String = ―hell‖;
3. var k:String = ―ActionScript 3.0″;

What’s the result when we compare each of the three variables?

Try it in your IDE.

This is my result, is the same with yours?

From this result, we know that, i > j > k. Here, ActionScript use the character code to compare. What you
need to know is that, from ―a-z‖, the corresponding character code is the smallest one, and z has the biggest
one, it means that from ―a-z‖ is order by ascending. Further more, upper case character is smaller than the
lower case one. When ActionScript compare two strings, it compares their character codes, from the first
one, if the first ones are equal, and then go to the next one.

If we compare ―hello‖ and ―hell‖ in ActionScript, we won’t get a result until we compare the last one. And if
we compare the ―hello‖ with ―ActionScript‖, we could easily get the result by just comparing the first
characters, ―h‖ > ―A‖.

Maybe this is not the result you want; maybe you want to compare them by the dictionary order. You’ll know
how to get a suitable version for you after we talk about the Array.

The left four operators have much to do with class hierarchy, so, discussed them after you know some basic
concepts about the class.

Equality operators

The results of comparison are not only including greater/less than, but also equality. Correspondingly, there
are equality operators in ActionScript. The equality operators take two operands, compare their values, and
return a Boolean value.

There are four equality operators:

1. == Equality
2. != Inequality
3. === Strict equality
4. !== Strict inequality

When you use the == operator or != operator with integer values, they work as you learn in mathematics.
When you perform them on string values, they work as we say in the relational operators.

For the primitive values, the equality operators compare their values, for the complex values, compare their
references.

Now, let’s talk about the difference between equality and strict equality, and this is the same in inequality
and strict inequality.

See the following code and output.


When we compare i and j with equality operator, it returns true, and it returns false when we use the strict
inequality.

Actually, the Boolean variable j is converting into the integer value 1 automatically when we use the equality
operator, but it doesn’t happen when we use the strict inequality operator.

In strict inequality mode, only the numeral type values, such as int, uint and Number will be auto converted
while in the normal equality mode, all the types will be auto converted. And this is the difference.

Beginning ActionScript 3.0 – Operators 4


When we talk about the relational operators, we mention that ActionScript use the character code for
comparison.

Introduction

Now, let’s do an experiment.

We declare an Array first, and then assign it some int values. If you don’t know the Array type, just consider
it as a container, and we can put some int type values in it. Then we sort the int values in the Array by using
the internal method, and print the result.
OK, see the result? It seems that the sort method consider the int type values as string type values. If you
want the sort method treat the values as int type, you need to designate the parameters.

Suppose we need to sort the int values by descending order. We can write the code as follows.

We use Array.NUMERIC to point out that the values should be treated as numeral values, and the
Array.DESCENDING figures out that the order should be descending. Besides these two parameters, we
have one more operators between them, it’s ―|‖ operator. This operator is called bitwise or.

Bitwise logical operators

The bitwise operators take two operands and perform bit-level logical operations.

For each bit, the rules of bitwise or can be writing as:

1. 0 | 0 = 0;
2. 0 | 1 = 1;
3. 1 | 0 = 1;
4. 1 | 1 = 1;

Check the help document, you can find that the Array.NUMERIC is a uint type value 16, and the
Array.DESCENDING is a uint value 2. Further more, all the public constants in Array, such as
Array.CASEINSENSITIVE and Array.RETURNINDEXEDARRAY, are all can be writing as 2^n. It means,
only one ―1‖ appears in the constant values, other bits are all zeros.

If you perform the ―bitwise or‖ operation on the constants, you can get interesting results.
Eh, it seems that we perform the ―bitwise or‖ operation on Array.CASEINSENSITIVE with
Array.DESCENDING will get a uint value 3. You can try this result simply by pass the int value 3 to the sort
method and see whether is the same result with the one you pass the constants. Try this in your own IDE.

From the name bitwise operator, you can infer that these operators should have much to do with the bits.
Let’s write down the 2’s complement code of Array.CASEINSENSITIVE and Array.DESCENDING, their
corresponding uint type values are 1 and 2.

So, when you pass a uint type parameter 3, the sort method can easily know that, the
Array.CASEINSENSITIVE and Array.DESCENDING have been designated by checking the bits. Because
the first bit is 1 and it means Array.CASEINSENSITIVE, so does the second bit.

Remember all the constants only has one bit valued 1. So, when you perform the bitwise on different
constants, they won’t affect each other. With this method, you can store different instructions and just use
one variable.

You may think this is a tricky skill, but it appears very often, especially on some open source code. So, it
would help when you see some similar code.

Besides the bitwise or operator, there are ―bitwise and‖ and ―bitwise xor‖.

1. & Bitwise AND


2. ^ Bitwise XOR
3. | Bitwise OR
The rules of ―bitwise and‖ are as follows:

1. 1 & 1 = 1;
2. 1 & 0 = 0;
3. 0 & 1 = 0;
4. 0 & 0 = 0;

When there is a zero, the result is zero.

The rules of ―bitwise xor‖ are as follows:

1. 1 ^ 1 = 0;
2. 1 ^ 0 = 1;
3. 0 ^ 1 = 1;
4. 0 ^ 0 = 0;

The same bits turns to be 0, and different bits turns to be 1.

In fact, there is still one more operator we need to introduce here, it’s ―bitwise logical not‖. According to
ActionScript, it was grouped in the Unary operators. Now, we introduce the rules of this operator.

1. ~1 = 0;
2. ~0 = 1;

This operator can be use for getting the opposite value.

When you meet some problems with the bitwise operators, maybe you can write down the operands in 2’s
complement code, and then use the corresponding rules, you’ll get the result.

OK, tell you another tricky skill here. By using the ―bitwise xor‖, we can swap two variable’s value unaided
any other variables.
Beginning ActionScript 3.0 – Operators 5
There is a similar type with bitwise logical operators, and we call them logical operators. These two kinds of
operators have similar rules, but deal with different operands.
Logical operators

Just like the bitwise logical operators, the logical operators take two operands and return a Boolean result.
And there is not corresponding operators to ―bitwise logical xor‖.

1. && Logical AND


2. || Logical OR

Note: &&’s precedence is higher than ||’s.

Write some code for warming up

From the code and the result, we can infer the rules of && operator and || operator.

The rules of && operator:

1. true && true = true;


2. true && false = false;
3. false && true = false;
4. false && false = false;

When there is a false, the result is false.

The rules of || operator:

1. true || true = true;


2. true || false = true;
3. false || true = true;
4. false || false = false;

When there is a true, the result is true.

Like the bitwise logical operator, we need to introduce a Unary operator here, it’s logical not, ―!‖.

The rules of ―!‖ operator:

1. !true = false;
2. !false = true;

En, get the opposite value.

If you replace the true with 1, false with 0 and the corresponding operators, you can get the rules of
corresponding bitwise operators.

Short-circuited

OK, tricky time.

Look at the rules of && carefully. When there is a false, the result should be false. When you write some
code like:

1. (exp1) && (exp2);

You can quickly get the false result if the exp1’s Boolean value is false, you don’t need to evaluate exp2. If
exp1’s Boolean value is true, then you need to evaluate the value of exp2. And the complier does it this way.

Run the following code, and then see the output.

1. var a:int = 0;
2.
3. trace(false &&(a++));
4. trace(a);

When we print the value of ―a‖ using trace(a), we can find that the value of ―a‖ is still 0, the expression ―a++‖
didn’t execute.

We call this short-circuited. And there is a similar situation in || operator.

Run the following code.

1. var a:int = 0;
2.
3. trace(true || (a++));
4. trace(a); // output 0
5.
6. (false || (a++));
7.
8. trace(a); // output 1

If we know the first expression is true, then the second expression won’t execute. If the first expression is
false, then the second expression will be executed.

Remember, you can use the logical operators to join many expressions, and the short-circuited is also
works.

1. var a:int = 0;
2.
3. trace(false || true || (a++));
4. trace(a); // output 0

For this tricky skill, my suggestion is don’t write some code like

1. (exp1) && (var++) or (exp1) || (var–);

This may cause many problems, because the value of var depends on the first expression.

You need to know this tricky skill, maybe you’ll use this to find some bugs.

Still remember the associativity? We said that the assignment operators and the conditional (?:) operator are
right-associative, while other operators are left-associative.

Now, it’s time for the conditional operator and assignment operators.
Conditional operator

This operator is a shorthand method of applying the if…else conditional statement. It is a ternary operator,
which means that it takes three operands.

?: Conditional

Since you may don’t know the if…else statement, I just write some code to show you the usage of this
operator.

With if…else statement:

1. function greater(a:int, b:int):int {


2. if(a >= b)
3. return a;
4. else
5. return b;
6. }
7.
8. trace(greater(2,3));

With the conditional operator:

1. function greater(a:int, b:int):int {


2. return a >= b ? a : b;
3. }
4.
5. trace(greater(2,3));

Focus on the statements inside the ―{―and ―}‖.

The condition is often using in this form:

1. exp1 ? exp2:exp3

If the Boolean value of exp1 is true, then return exp2, if false, then return exp3.

Assignment operators

The conditional operator is a shorthand method of if…else statement. Similarly, most of the assignment
operators are shorthand operators of some operators. The assignment operators take two operands and
assign a value to one operand, based on the value of the other operand.
1. = Assignment
2. *= Multiplication assignment
3. /= Division assignment
4. %= Modulo assignment
5. += Addition assignment
6. -= Subtraction assignment
7. <<= Bitwise left shift assignment
8. >>= Bitwise right shift assignment
9. >>>= Bitwise unsigned right shift assignment
10. &= Bitwise AND assignment
11. ^= Bitwise XOR assignment
12. |= Bitwise OR assignment

Ignored the ―=‖ operator, because you know it very clearly. Let’s just focus on the left operators.

These operators are all form by some operator and the assignment sign ―=‖, and shorthand operators for the
some operator.

Look at the following code.

1. var a:int = 1;
2. var b:int = 2;
3.
4. a = a + b;

If we use the ―+=‖ operator, the last statement can be rewrite as:

1. a += b;

Try it on your own IDE.

So, using the assignment operator in this way:

1. var1 operator= var2;

is equals to:

1. var1 = var1 operator var2.


OK, that’s all for the operators. In the operators’ series, we still missed some operators; I will talk about them
when there is a suitable time.

Beginning ActionScript 3.0 – Operators overview


After we know how to store the data, we need to know how to perform operations on the data. That means
we need the data operation. In every programming language, there is a corresponding Semiotic system, so
does ActionScript. In most case, in order to make it easier for us to learn the Semiotic system, the language
designer often takes the arithmetic Semiotic system as a base.

Overview

In ActionScript 3.0, operators are special functions that take one or more operands and return a value. An
operand is a value—usually a literal, a variable, or an expression—that an operator uses as input. Now, let’s
write some code to test the arithmetic operations.

1. var a:int = 5;
2. var b:int = 10;
3. var c:int;
4.
5. c = a+b;
6. trace(c); //output 15
7.
8. c = a*b;
9. trace(c); //output 50
10.
11. c = b/a;
12. trace(c); //output 2
13.
14. c = a-b;
15. trace(c); //output -5

Note: the multiplication notation is ―*‖, not ―X‖.

OK, the operations here are the same as they do in arithmetic.

Except the arithmetic operators, there are primary operators, logical operators, postfix operators, relational
operators, and bitwise operators and so on in ActionScript 3.0. We’ll discuss them later.

In general, all the operators can be dividing into be unary, binary, or ternary operator. From their name, you
may guess the difference is all about the operands. Only one operand needed in unary operator. For
example, the increment (++) operator, and it takes only one operand. A binary operator takes two operands.
For example, the division (/) operator takes two operands. And the ternary operator takes three operands.
For example, the conditional (?:) operator takes three operands.

Operator precedence and associativity

Now, guess the output of the following code

1. var a:int = 1;
2. var b:int = 2;
3. var c:int = 3;
4. var d:int;
5.
6. d = a + b * c;
7. trace(d);
8.
9. d = (a + b) * c;
10. trace(d);

Due to our mathematic knowledge, the first output is 7, and the second will be 9, because it uses the
parenthesis to change the precedence. In fact, it is the same in ActionScript. Run the code, you will get the
following result.

We all know the second output will be 9, because our math teacher told us. But, does our math teacher tell
the flash player this? If not, why the flash player knows the second output should be 9, not other value.

The answer is the operator precedence, the language designers defines the operator precedence. With the
operator precedence, our ActionScript compiler can determine the order in which operators are processed.
The following image shows all the operators, and grouped them with the same precedence. And the above
one’s priority is larger than the below one. For example, the [ ] operator’s precedence is larger than x++. You
can easily determine the precedence by the following picture.

Another question now, what will happen when two or more operators of the same precedence appear in the
same expression. Here is an example from the official help document.

1. trace(3 > 2 < 1);


2. trace ((3 > 2) < 1 );
3. trace (3 > (2 < 1) );

In these cases, the compiler uses the rules of associativity to determine which operator to process first. All of
the binary operators, except the assignment operators, are left-associative, which means that operators on
the left are processed before operators on the right. The assignment operators and the conditional (?:)
operator are right-associative, which means that the operators on the right are processed before operators
on the left.

According to the associativity rules, the output will be false, false, and true.
Beginning ActionScript 3.0 – Control Flow
After we talking about too much about the operators, let’s go to something new now.

Introduction

Have a look at the below schedule first.

1. 8:20—8:40 have breakfast


2. 9:00—9:30 practice calligraphy
3. 9:35—9:40 check the email
4. 9:40—10:00 if there is a new email, reply it, or read blogs.
5. 10:00— …. Begin to write the new article of this series, until the new one was finished

Suppose this is my schedule, from this schedule, you may know what I was doing at some fixed time, but
maybe not exactly at sometime.

If the time is between 8:20 and 8:40, I was having my breakfast; and between 9:00 and 9:30, I was
practicing the calligraphy. From 8:20 to 9:40, you can consider my action was chronological, or sequenced.
But, you don’t know what things I did exactly between 9:40 and 10:00, because it depends whether there is
a new email for me. So, it’s conditional. Further more, you know I begin to write the article from 10:00, but
you don’t know the time I stop. And you can consider this is a loop, and the terminal condition is that the
article was finished.

You know, programming is a way of modeling the real world. So, let’s translate the schedule into
ActionScript.

1. var newEmail:Boolean = false;


2. var articleFinished:Boolean = false;
3.
4. trace(‖have breakfast‖); //sequence
5. trace(‖practice calligraphy‖);
6. trace(‖check the email‖);
7.
8. if(newEmail) { //selection
9. trace(‖Reply the email‖);
10. } else {
11. trace(‖Read blogs‖);
12. }
13.
14. while(!articleFinished) { //repetition
15.
16. trace(‖Busy writing‖);
17. articleFinished = true;
18. }

Here, we mention three concepts: sequence, selection and repetition.

Sequence means the statements execute in order.

Selection means one or more statements’ execution depends on the state of your program.

Repetition means one or more statements will be repeated, until your program reaches a certain state.

These three concepts are basic concepts in programming languages. They’re the cornerstones of
procedural-oriented programming language.

In fact, the mainstream object-oriented programming languages both support the procedural way and object-
oriented way. Further more, when you build small application with ActionScript, you may use the procedural
way in most cases. Remember, the procedural-oriented or object-oriented is just a way of solving the
problems.

Sequence

In the above example, the sequence statements are:

1. trace(‖have breakfast‖); //sequence


2. trace(‖practice calligraphy‖);
3. trace(‖check the email‖);

When you run this code, you will see the output one by one in the order of the code.

Sequence is the most general thing in programming. When you write down your code without conditional or
loop, you don’t need to consider the order of the statements’ execution.
In most cases, the code is running sequenced. The order of the statements’ execution depends on the
position it take in the source code. This is true in most programming languages, but not always true in
ActionScript.

1. trace(variable);
2. var variable:String = ―Tricky compiler‖;
3. trace(variable);

Here, we use a variable before we declare it. And in some other programming languages, we will get a
compiler error. But, this won’t happen in ActionScript.

Run the code and then tell me the output.

Maybe you know the output is:

Because of the hoisting, an ActionScript mechanism, you can use the variable before you declare it. Though
it maybe nonsense, you can use it anyway.

Due to this mechanism, the code will be:

1. var variable:String;
2. trace(variable);
3. variable= ―Tricky compiler‖;
4. trace(variable);

after the code get compiled. It means all the declare statement will be put into the beginning of this scope
domain. And scope will be discussed when we talk about the function.

I mention this example here, just want to tell you, sometimes what you write may not what you get :). Know
something about the mechanism of the language you use will be helpful sometimes.

Beginning ActionScript 3.0 – Conditionals 1


Go on with the control flow, today we’re going to talk about the conditionals. In ActionScript, the conditionals
including if, if…else, if…else if… and switch. Now, let’s introduce them one by one.

if
The statement ―if‖, is a basic conditional statement. When your need to execute a block of code depends on
some condition. You will need this statement.

The form is:

1. if (expression) {
2. //a block of code here
3. }

When the Boolean value of expression is true, the code between the brackets will be executed, as the
following code shows:

1. var a:int = 15;


2.
3. if (a > 10) {
4. trace(‖a > 10″);
5. }

Remember if the expression is not a Boolean expression, which means the value it returns is not a Boolean
value, then the value of the expression will be auto converted into the Boolean value by the mechanism
called implicit coercion. We’ll spend some talk about the conversion, but not now.

The following code shows the implicit coercion.

1. var a:int = 15;


2.
3. if (a) {
4. trace(‖a > 10″);
5. trace(Boolean(a));
6. }

Here, we take a as the expression of if statement. So, the value of a will be converted into a Boolean value,
and the value is true, because the value of ―a‖ is not zero. Eh, 0, null, undefined, NaN and ―‖ (empty string)
will converted to false in the Boolean conversion.

if…else

Sometimes, you need to execute a block of code if that condition exists, or execute an alternative block of
code if the condition does not exist. Then you’ll need the ―if…else‖ statement.
1. If (expression) {
2. // code part 1
3. } else {
4. // code part 2
5. }

When the Boolean value of expression if true, code part 1 will be executed. If not, the code part 2 will be
executed.

1. var a:int = 10;


2.
3. if (a > 10) {
4. trace(‖a > 10″);
5. } else {
6. trace(‖ a <= 10″ );
7. }

if…else if…

If the if or if…else statement can’t satisfy your requirement, maybe you need to test for more than one
condition. For example, you need to know the season in your program, and there’re four choices. In this
time, the ―if…else if…‖ statement will help.

1. var i:uint = new Date().getMonth();


2.
3. // the Month you get from the Date object is from 0-11
4. var month:uint = i + 1;
5.
6. if( month >= 3 && month <= 5 ) {
7. trace(‖Spring‖);
8. } else if ( month >= 6 && month <= 8 ) {
9. trace(‖Summer‖);
10. } else if ( month >= 9 && month <= 11 ) {
11. trace(‖Autumn‖);
12. } else if ( month == 12 || month == 1 || month == 2 ) {
13. trace(‖Winter‖);
14. } else {
15. throw new Error(‖System bug‖);
16. }

So, the form of this statement is:

1. if (expression1) {
2. // code block 1
3. } else if (expression2) {
4. // code block 2
5. }
6. ……
7. } else if (expression n) {
8. // code block n
9. }
10. else {
11. // other code
12. }

The last ―else‖ statement is optional. You can ignore this part if you don’t need it.

In the ―if…else if…‖ statement, only one code block will be executed. So you should be careful when there is
more than one expression’s Boolean value is true. Which code block should be executed depends on the
order of the expression appear.

Look at the following code.

1. var i:uint = new Date().getHours();


2.
3. trace(‖Hour: ‖ + i);
4.
5. if( i < 12 ) {
6. trace(‖before noon‖);
7. } else if ( i < 9 ) {
8. trace(‖A little earlier‖);
9. } else {
10. trace(‖oh, after 12″);
11. }

When I run this code, I get the following result.


It’s not what I want; I want it outputs ―A little earlier‖.

As you see, we put the big range ―i < 12‖ before the smaller one ―i < 9‖. So, if the second expression is true,
the first one must be true, and the code in the first expression’s block will be executed, and then we can’t get
what we want.

So, the lesson here is put the small range first, or specify each condition.

You can change the code into:

1. if( i >=9 && i < 12 ) {


2. trace(‖before noon‖);
3. } else if ( i < 9 ) {
4. trace(‖A little earlier‖);
5. } else {
6. trace(‖oh, after 12″);
7. }

or:

1. if( i < 9 ) {
2. trace(‖A little earlier‖);
3. } else if ( i < 12 ) {
4. trace(‖before noon‖);
5. } else {
6. trace(‖oh, after 12″);
7. }

Both of them can get the result we want.

Beginning ActionScript 3.0 – Conditionals 2


Go on with the previous section, after the ―if…else if…‖ statement, we need to know the last conditional
statement, Switch.

In most case, the ―if…else if…‖ statement can be rewrite with the switch statement. And the switch
statement seems to be more readable. Instead of testing a condition for a Boolean value, the switch
statement evaluates an expression and uses the result to determine which block of code to execute. Blocks
of code begin with a case statement and end with a break statement.

So, its form is:

1. Switch (expression) {
2. case value 1:
3. // code block 1
4. break;
5.
6. case value 2:
7. // code block 2
8. break;
9.
10. ……
11.
12. case value n:
13. // code block n
14. break;
15.
16. default:
17. // default code
18.
19. break;
20. }

In the switch statement, the value of the expression will be evaluated firstly. Then compare the value of the
expression with all the values appear in the case statement, if there is a equal value, then execute the code
after the case statement, till it meets a break statement. If there is no value equals to the expression, then
the default block will be executed, also it terminates when it meets the break statement.

Using the switch statement to rewrite the example in ―if…else if…‖ statement, we can get the following
result.
1. var i:uint = new Date().getMonth();
2. // the Month you get from the Date object is from 0-11
3. var month:uint = i + 1;
4.
5. switch (month) {
6. case month >= 3 && month <= 5:
7. trace(‖Spring‖);
8. break;
9.
10. case month >= 6 && month <= 8:
11. trace(‖Summer‖);
12. break;
13.
14. case month >= 9 && month <= 11:
15. trace(‖Autumn‖);
16. break;
17.
18. case month == 1 || month == 2 || month == 12:
19. trace(‖Winter‖);
20. break;
21.
22. default:
23. throw new Error(‖System bug‖);
24. }

If you run the code, you can get something surprise you.

This is my result. Though the code can be complied, but you can’t get the result you want. Actually, the
statements with the logical operators, such as:

1. case month >= 3 && month <= 5:

is equals to:
case true;

If you don’t believe it, you can pass the Boolean value true into the switch as the expression.

See it? I’m not cheating you

According to the form of switch, there should be a value after the ―case‖ statement. So, the correct switch
version of this example should be:

1. var i:uint = new Date().getMonth();


2.
3. // the Month you get from the Date object is from 0-11
4. var month:uint = i + 1;
5.
6. switch (month) {
7. case 3:
8. trace(‖Spring‖);
9. break;
10.
11. case 4:
12. trace(‖Spring‖);
13. break;
14.
15. case 5:
16. trace(‖Spring‖);
17. break;
18.
19. case 6:
20. trace(‖Summer‖)
21. break;
22.
23. case 7:
24. trace(‖Summer‖);
25. break;
26.
27. case 8:
28. trace(‖Summer‖);
29. break;
30.
31. case 9:
32. trace(‖Autumn‖);
33. break;
34.
35. case 10:
36. trace(‖Autumn‖);
37. break;
38.
39. case 11:
40. trace(‖Autumn‖);
41. break;
42.
43. case 12:
44. trace(‖Winter‖);
45. break;
46.
47. case 1:
48. trace(‖Winter‖);
49. break;
50.
51. case 2:
52. trace(‖Winter‖);
53. break;
54.
55. default:
56. throw new Error(‖System bug‖);
57. }

Maybe, you will think this version is a little too verbose.

OK, remember the break statement? The execution will step out the switch block when it meets the break
statement. That means if there is no break statement, the execution will go on. Got it?
Let’s do it.

1. var i:uint = new Date().getMonth();


2.
3. // the Month you get from the Date object is from 0-11
4. var month:uint = i + 1;
5.
6. switch (month) {
7. case 3:
8. case 4:
9. case 5:
10. trace(‖Spring‖);
11. break;
12.
13. case 6:
14. case 7:
15. case 8:
16. trace(‖Summer‖);
17. break;
18.
19. case 9:
20. case 10:
21. case 11:
22. trace(‖Autumn‖);
23. break;
24.
25. case 12:
26. case 1:
27. case 2:
28. trace(‖Winter‖);
29. break;
30.
31. default:
32. throw new Error(‖System bug‖);
33. }

Ignore the break statement, the flow will fall out.


Now, remember this trick, sometimes you may meet some code like this, or write some code like this.

If you don’t the flow fall out, remember the break statement. Furthermore, keep the switch block simple,
don’t try to do too much in it.

Beginning ActionScript 3.0 – Looping 1


Ok, still the control flow. After the conditionals, let’s turn to the looping statements, which includes while,
do…while, for, for…in and for each…in. But here I just want to show you the usage of while, do…while and
for, I want to put for…in and for each…in with the Array class.

When you want to do something repeating, you can use the looping statements. Looping statements allow
you to perform a specific block of code repeatedly using a series of values or variables.

In general, when you want to use the looping statement, you need to designate a counter variable, a test
condition and update the counter. The counter variable counts the time that the looping block executes. And
the test condition test the counter with some other value, which often refers to the time you want the looping
block executes. Updating the counter is very important, if you forget it, the loop will become infinite loop.

While

The ―while‖ loop is like an ―if statement‖ that repeats as long as the ―condition‖ is true and the form of while
statement is:

1. while ( condition ) {
2. // code block
3. }

Suppose we want to print the integers from 1 to 50, we can use the while statement like this.

1. var i:int = 1; // declare the counter variable


2.
3. while ( i <= 50 )
4. trace(i);

Run the code.


And then

1. …
2. …
3. …
you can get an error, after 15 seconds.

As you see, in this form, it only requires the condition statement, so, it’s easy to forget updating the counter
variable. If you forget updating the counter, the loop will become an infinite loop.

So, we should update the counter variable.

And the new version is here.

1. var i:int = 1; // declare the counter variable


2. while ( i <= 50 )
3. trace(i);
4. i++; // update the counter

Eh, if you try to run the code, you have to wait another 15 seconds

So, what’s the problem here?

The answer is the braces; we don’t use the braces here. If you don’t use the braces to enclose the code
block, only the first statement following the while statement will be executed during the looping. So, ―i++;‖ will
be executed after the looping is finished.

I suggest you always enclose the block of code in braces ({}). Although you can omit the braces if the block
of code contains only one statement, it increases the likelihood that statements added later will be
inadvertently excluded from the block of code. If you later add a statement that you want to include in the
block of code, but forget to add the necessary braces, the statement will not be executed as part of the loop.
This suggestion is also for conditionals.

OK, the correct version is as below:

1. var i:int = 1; // declare the counter variable


2.
3. while ( i <= 50 ) {
4. trace(i);
5. i++; // update the counter
6. }

If you want to update the counter in the condition test statement, then be careful about the boundary
conditions. And the correct version will be:

1. var i:int = 0; // declare the counter variable


2.
3. while ( i++ < 50 ) {
4. trace(i);
5. }

This equals to:

1. var i:int = 0; // declare the counter variable


2. while ( i < 50 ) {
3. i++;
4. trace(i);
5. }

When you using the looping statement, remember to update the counter variable, and be careful about the
boundary conditions.

do…while

Similar but a little different from the while loop, the do…while loop guarantees that the code block is
executed at least once, because the condition is checked after the code block is executed.

And the form of do…while is as blow:

1. Do {
2. //code block
3. } while (condition);

The difference between is that the while loop test the condition first, while the do…while loop execute the
code block first. So, the code block in do…while is executed at least once.

The following example shows their difference.

1. while ( false ) {
2. trace(‖The while loop‖);
3. }
4.
5. do {
6. trace(‖The do…while loop‖);
7. } while ( false );

Remember the code block in do…while loop will be executed before testing the condition.
Beginning ActionScript 3.0 – Looping 2
Go on with looping statements, in last section, we talk about the while and do…while. Now, let’s turn to next
one, for.

for

Maybe the ―for loop‖ is the most common looping statement. Let’s take a look at its form first.

1. for ( initial block; test block; update block) {


2. // code block
3. }

And the execution order of ―for loop‖ is:

1. the initial block, and the initial statement will be executed only once while entering the ―for loop‖;

2. the test block; if true, then go to the code block, or finish the loop;

3. code block;

4. the update block, then go to the test block;

The ―for statement‖ put the three factors inside it. In general, we declare the counter variable at the initial
block, test the condition in the test block, and update the counter at the update block.

If we want to print 1-50 again with ―for loop‖, our code will be:

1. for(var i:int = 1; i <= 50; i++) {


2. trace(i);
3. }

This is the regular form of ―for loop‖, actually, the compiler won’t force you putting all the three factors inside
the parenthesis ―()‖. You can declare the counter variable before the ―for loop‖, or put the test statement and
update statement inside the code block.

Let’s rewrite the code.

Like this:

1. var i:int = 1; // declare the counter variable


2.
3. for(;;) {
4. if( i > 50 ) // test statement
5. break;
6.
7. trace(i);
8. i++; // update the counter variable
9. }

Or even like this:

1. for(var i:int = 1;i <= 50 ;trace(i),i++) {


2. }

These two ways are not recommended, because both of them may confuse you. The first one do too much
in the code block, the second one put the code block inside the update block.

Keep each block simple; just let them in charge of their own responsibility.

Nested loop

Sometimes, just one loop can’t satisfy our requirement. We need to control two or more counter variables
inside the loop. For example, when you deal with the matrix, you may need two variables to indicate the row
and the column, or so on. In these situations, you need the nested loop.

The nested loop means you nest the loop inside the loop. You can use the while statement or for statement.

Now, let’s write some code to get familiar with the nested loop. Remember the multiplication table? Maybe
we all had recited it during our primary school. Let’s try to print all the expressions of the multiplication table
with ActionScript. And the form of the expression is as follows:

1. 1*1=1
2. 2*1=2
3. 2*2=4
4. 3*1=3
5. 3*2=6
6. ……
7. 9 * 9 = 81

And the range is from 1 to 9.

The form of the expression can be rewrite as:

1. i * j = the product of i and j


Obviously, we need to variables here, for i and j. And, we can put I into the outer loop, j into the inner loop.
So, the code will like:

1. for(var i:int = 1; i < 10; i++) {


2. for( var j:int = 1; j < 10; j++) {
3. trace(i + ‖ * ‖ + j + ‖ = ‖ + i*j );
4. }
5. }

Look at the result carefully.

The expressions in red rectangle are the same; in fact, we just need to print one of them. And you just need
to modify one condition, and then the redundant expressions will disappear.

Eh, for the first version of print the multiplication table, you can use just one loop, but it’s not so readable.

1. for(var i:int = 1; i <= 81; i++) {


2. trace( ((i-1)%9+1) + ‖ * ‖ +(Math.ceil(i/9))+ ‖ = ‖ + ((i-1)%9+1)*Math.ceil(i/9));
3. }

Aha, don’t try to write your code like this, it may make you boss angry if he read the code .
Beginning ActionScript 3.0 – Looping 3
After the talking about the looping statements, today, we’re going to talk about some keywords we use in
looping.

break

We mention this keyword when we talk about the switch statement. In switch statement, we use the break
statement to jump out from the switch block. There is a similar effect in looping statements. We often use the
break statement coordinate with the ―if statement‖ to break the whole loop when the program meets some
conditions.

In most case, you’ll use this statement in the nested loop, you can use this statement to skip the inner loop,
go on with the outer loop as your program meets some conditions.

The general form is like this:

1. for( initial statement; conditional statement; update counter) {


2. for( initial statement; conditional statement; update counter) {
3.
4. if( expression) {
5. break;
6. }
7.
8. //inner looping code block
9. }
10.
11. //outer looping code block
12. }

For example, suppose we need to print all the prime numbers between 100 and 200. A prime number (or a
prime) is a natural number which has exactly two distinct natural number divisors: 1 and itself. To check N
for primality the largest prime factor needed is just less than the square root of N.

So, our code can be writing as follows:

1. var isPrime:Boolean = false;


2.
3. for(var i:int = 100; i <= 200; i++) {
4. var max:int = int(Math.sqrt(i));
5.
6. isPrime = true;
7. for(var j:int = 2; j <= max; j++) {
8. if(i % j == 0) {
9. isPrime = false;
10. break;
11. }
12. }
13.
14. if(isPrime)
15. trace(i);
16. }

Here, we use i indicating the test number, and j indicating the divisor. If we’ve already know that the test
number can be divided exactly by some number, then we can know that this test number is not a prime
number and we don’t need to go on the inner loop, so, we can use the break statement here to terminate the
inner loop.

continue

Besides break, there is another keyword we can use during the looping, it’s ―continue‖. With this keyword,
you can skip the left code and begin next iteration.

The general form is:

1. for( initial statement; conditional statement; update counter) {


2.
3. if(expression) {
4. // code block A;
5. continue;
6. }
7.
8. //code block B;
9. }

When the Boolean value of expression is true, the code block A will be executed, then the continue
statement, and the code block B will be ignored and begin the next loop.

Example time :).


Now, I want to print all the non-leap years between 1900 and 2000. In order to find the non-leap years, we
can find the leap year and skip them, then we can get all the non-leap years.

According to the definition of leap year, we can find that the algorithm can be represent as ―(year % 4 == 0)
&& (year % 100 != 0) ) || (year % 400 == 0)‖ in ActionScript. So, our code can be written as:

1. for(var i:int = 1900;i <= 2000 ;i++) {


2.
3. if( ( (i % 4 == 0) && (i % 100 != 0) ) || (i % 400 == 0) ) {
4. ;
5. } else {
6. trace(i);
7. }
8. }

Here, we test a certain year is a leap year or not, if leap year, then do nothing, or, print it. Think a little more,
when we meets the leap year, we do nothing; it means we need to begin another iteration. Aha, it’s the time
for the continue statement.

Let’s use the continue statement to rewrite the example.

1. for(var i:int = 1900;i <= 2000 ;i++) {


2.
3. if( ( (i % 4 == 0) && (i % 100 != 0) ) || (i % 400 == 0) ) {
4. continue;
5. }
6.
7. trace(i);
8. }

The continue statement here skips the print statement and begin the next iteration.

Please remember the difference between continue statement and break statement. In fact, they often
cooperate with each other due to their different functions. Sometimes, you may meet some code like the
following form:

1. While() { //outer loop


2. //code block 1
3. While{ //inner loop
4. //code block 2
5. if (expression)
6. break;
7. //code block 3
8. }
9.
10. If (expression)
11. continue;
12. //code block 4
13. }

Using these two keywords, you can build some flexible applications, eh, but remember to let your code
readable.

Beginning ActionScript 3.0 – Looping 4


As you know, the break statement can terminate the current loop, while the continue statement can skip the
left code in current iteration and begin next iteration. Today, we introduce something new, which can
cooperate with the break and continue.
label

When you using nested loop, you may want flow jump out from the inner loop to the main program directly,
not from one loop to another loop. Or, when you using the switch statement inside the looping statement,
and you want the break statement inside switch statement terminates the whole loop, not just jump out the
switch block. In these situations, you need the label statement.

The genera form of label is:

label: statement

The label here refers to an identifier that you want to link with the statement. And the statement here refers
to the statements you want to link with the identifier. So, you can use the label statement like this:

1. var i:int;
2. initial: i = 0;

or like this:

1. outer: while (expression ) {


2. //code block a
3.
4. while ( expression ) {
5. if (expression)
6. break outer;
7. // code block b
8. }
9. //code block c
10. }

Or even follow the label by a code block.

1. initial: {
2. var i:int = 0;
3. var j:int = 1;
4. var k:int = 2;
5. }

If you follow the label by a code block, you can’t use the continue statement with the label. That’s because if
you use the continue statement, the code block will become an infinite loop. And you can use the break
statement to jump out from the current code block.

If you try to use the continue statement in the code block, you will get the following result.

But you can use the break statement in the code block, because the flash player knows that you want to join
out from the current code block. So, the following code can get the result you want.

1. testLabel:{
2. trace(‖hello‖);
3. break testLabel;
4. trace(‖System bug‖);
5. }
6.
7. trace(‖ActionScript‖);

Remember, you can use the break statement to join out from the current code block, which means, you
should use the break statement inside the block.
If you try to use the break statement outside the block, you will get an error.

After some wrong cases, let’s take a look at the correct usage of the label statement with continue.

Remember our example about print the prime numbers between 100 and 200?

1. var isPrime:Boolean = false;


2.
3. for(var i:int = 100; i <= 200; i++) {
4. var max:int = int(Math.sqrt(i));
5.
6. isPrime = true;
7.
8. for(var j:int = 2; j <= max; j++) {
9. if(i % j == 0) {
10. isPrime = false;
11. break;
12. }
13. }
14.
15. if(isPrime)
16. trace(i);
17. }

Now, let’s use the label statement with continue to rewrite that example.

1. outer:for(var i:int = 100; i <= 200; i++) {


2.
3. var max:int = int(Math.sqrt(i));
4.
5. for(var j:int = 2; j <= max; j++) {
6. if(i % j == 0) {
7. continue outer;
8. }
9. }
10.
11. trace(i);
12. }

When flash player meets the continue with a label, the flow will jump to the code block designated by the
label and execute the code from the top of the code block; and when the flash play meets the break
statement with a label, the flow will jump out from the code block and execute the code after the code block
designated by the label.

For example, if the code is like:

1. outer: while (true ) {


2.
3. //code block a
4. while ( true ) {
5.
6. //code block b
7. break outer;
8.
9. // code block c
10. }
11.
12. //code block d
13. }
14.
15. // code block e

Then the execution order will be:

1. 1. code block a
2. 2. code block b
3. 3. break outer
4.
5. 4. code block e

If the code is like:


1. outer: while (true ) {
2.
3. //code block a
4. while ( true ) {
5. //code block b
6. continue outer;
7. // code block c
8. }
9.
10. //code block d
11. }
12. // code block e

Then the execution order will be:

1. 1. code block a
2. 2. code block b
3. 3. continue outer
4. 4. code block a
5. ……

Though the label statement can may your code looks more concise, but I recommended you not to use the
label statement unless it is necessary. Because you only need to use the label statement in nested loop, and
use the label statement can make the program’s logic more complicated.

Keep things simple is a good style So, you just need to know the usage of the label statement, don’t use
them unless it is necessary.

Beginning ActionScript 3.0 – Summary of control flow


Now, let’s spend some time to review what we have talked about in the control flow.

At first, we talk about the schedule and introduce three concepts about the control flow, sequence, selection
and repetition.

Sequence means the statements execute in order.

Selection means one or more statements’ execution depends on the state of your program.

Repetition means one or more statements will be repeated, until your program reaches a certain state.
Then we discuss the conditionals.
―if‖ statement:

1. if( expression ) {
2. // code block
3. }

―if…else‖ statement

1. if (expression ) {
2. // code block a
3. } else {
4. // code block b
5. }

―if…else if…‖ statement.

1. if (expression ) {
2. //code block a
3. } else if ( expression ) {
4. // code block b
5. …..
6. } else if (expression) {
7. //code block n-1
8. } else {
9. //code block n
10. }

Remember, the expression will be converted to Boolean value if the expression is not a Boolean expression.
And only one code block will be executed, so, be careful about the condition when you using ―if…else if…‖
statement.

And the switch statement:

1. Switch (expression) {
2.
3. case value 1:
4. // code block 1
5. break;
6.
7. case value 2:
8. // code block 2
9. break;
10. ……
11.
12. case value n:
13. // code block n
14. break;
15.
16. default:
17. // default code
18. break;
19. }

You can refactor the ―if…else if…‖ statement with ―switch‖ statement. And sometimes you can ignore the
break statement to let the flow fall out.

After the discussion of conditions, we turn to the looping statements, such as while, do…while and for. And
the break, continue and label statement are also discussed.

When you use the looping statement, remember to declare the counter variable, test the condition and
update the counter variable. Further more, be careful about the boundary condition; be clear about ―greater
than‖ or ―greater than or equal‖ and so on.

For example, the two versions of print the numbers between 1 and 50:

The first one is less than or equal,

1. var i:int = 1; // declare the counter variable


2.
3. while ( i <= 50 ) {
4. trace(i);
5. i++; // update the counter
6. }

The second one is less than,

1. var i:int = 0; // declare the counter variable


2. while ( i++ < 50 ) {
3. trace(i);
4. }

The common usage of ―break statement‖:

1. jump out from the switch block;

2. jump out from the looping block;

3. jump out from the looping block designated by the label, when the break statement with label statement.

The common usage of ―continue statement‖:

1. Skip the left code in the looping block, and begin the next iteration.

2. The program flow will jump to the code block designated by the label and execute the code from the top of
the code block, if you use the ―continue statement‖ with a label statement.

That’s all for the control flow.

Keep things simple, makes your code maintainable and readable.

Beginning ActionScript 3.0 – Function Introduction


After the discussion about conditionals and looping, let’s turn to the new topic, function. Before our
discussion, let’s do some practice first.

Introduction

Now, your friend, a teacher in a school, needs your help. He wants to print the students’ scores of
mathematics, history and music in his class. And, he knows that you’re a genius developer, so he asks for
your help.

Suppose the poor teacher stores the scores in the corresponding array like below:

1. var math:Array = [70, 80, 65, 90, 85, 100];


2. var history:Array = [90, 89, 92, 82, 78, 95];
3. var music:Array = [72, 75, 89, 92, 65, 79];

So, your task is to print the values stored in the arrays.

Eh, it seems that we need to iterate all the values stored in the arrays. Remember the ―for statement‖?
Maybe we can use the ―for statement‖ or other looping statement for the iteration. And the version of ―for
statement‖ implementation is like below:

1. var math:Array = [70, 80, 65, 90, 85, 100];


2. var history:Array = [90, 89, 92, 82, 78, 95];
3. var music:Array = [72, 75, 89, 92, 65, 79];
4.
5. trace(‖============Mathematics==========‖);
6.
7. for(var i:int = 0; i < math.length; i++) {
8. trace(math[i]);
9. }
10.
11. trace(‖=============end===============\n‖);
12. trace(‖============History==========‖);
13.
14. for(i = 0; i < history.length; i++) {
15. trace(history[i]);
16. }
17.
18. trace(‖=============end===============\n‖);
19. trace(‖============Music==========‖);
20.
21. for(i = 0; i < music.length; i++) {
22. trace(music[i]);
23. }
24.
25. trace(‖=============end===============\n‖);

Run the code you can see the result in the output panel.

OK, that’s it, genius developer, your task is finished. Your friend very appreciates your excellent work. But,
he feels that the output format maybe need some change. He wants to know the index of each value. That
means he want to change the current output into:
Aha, a piece of cake, you think. You just need change the output statements in the iteration and then you
can get the result.

Eh, here you just need to modify three statements, but what if the teacher friend wants to print more kinds of
scores or change the output format to be another one.

OK, let’s go back to the code we write first. And the form is like:

1. trace(―subject‖);
2.
3. for(var i:int = 0; i < subjectArray.length; i++) {
4. trace(i + ―:‖ + subjectArray [i]);
5. }
6.
7. trace(‖end\n‖);

The similar code appears in the code we wrote three times.

Three times that means redundancy and hard to maintain here.

Look at the three blocks carefully; you can see the difference between each block is just the array name.

If we use a temporary Array type variable,

1. var subjectArray:Array;

Then, we can rewrite the code into:

1. trace(‖============Mathematics==========‖);
2.
3. subjectArray = math;
4.
5. for( i = 0; i < subjectArray.length; i++) {
6. trace(i + ―:‖ + subjectArray[i]);
7. }
8.
9. trace(‖=============end===============\n‖);
10. trace(‖============History==========‖);
11.
12. subjectArray = history;
13.
14. for( i = 0; i < subjectArray.length; i++) {
15. trace(i + ―:‖ + subjectArray[i]);
16. }
17.
18. trace(‖=============end===============\n‖);
19. trace(‖============Music==========‖);
20.
21. subjectArray = music;
22.
23. for( i = 0; i < subjectArray.length; i++) {
24. trace(i + ―:‖ + subjectArray[i]);
25. }
26.
27. trace(‖=============end===============\n‖);

Now, the only difference between each block is the assignment statement. Further more, if we can use
something short instead of the blocks, we can get more concise code.

Maybe like:

1. trace(‖============Mathematics==========‖);
2.
3. subjectArray = math;
4.
5. printScore();
6.
7. trace(‖============History==========‖);
8.
9. subjectArray = history;
10. printScore();
11.
12. trace(‖============Music==========‖);
13.
14. subjectArray = music;
15. printScore();

Here, ―printScore()‖ is stand for:

1. for( i = 0; i < subjectArray.length; i++) {


2. trace(i + ―:‖ + subjectArray[i]);
3. }
4.
5. trace(‖=============end===============\n‖);

If we can rewrite the code like this, it will be very convenient. Maybe we can declare the printScroe equals to
the block of code in somewhere else

Now, If the teacher friend want to print more kinds, you just need to paste the printScore() a few more times.
If the teacher wants to change the output format, you just need to change one trace statement.

Note: this is not an actual solution; don’t try to run the code. The actual solution will be given in the next
section

Beginning ActionScript 3.0 – Function First Sight


In last section, we use the printScore() stands for a block of code, in order to get rid of the redundancy and
make the code more easier to maintain.

Actual Solution

Now, it’s time for the actual solution, or you may kill me

In ActionScript, there is an important concept called function. Function is a block of code that carries out
specific tasks and can be reused in your program. And that’s exactly what we need now.

Let’s use function to rewrite the code.

1. var math:Array = [70, 80, 65, 90, 85, 100];


2. var history:Array = [90, 89, 92, 82, 78, 95];
3. var music:Array = [72, 75, 89, 92, 65, 79];
4.
5. trace(‖============Mathematics==========‖);
6. printScore(math);
7. trace(‖============History==========‖);
8.
9. printScore(history);
10. trace(‖============Music==========‖);
11.
12. printScore(music);
13.
14. function printScore(subjectArray:Array):void {
15. for( var i:int = 0; i < subjectArray.length; i++) {
16. trace(i + ―:‖ + subjectArray[i]);
17. }
18.
19. trace(‖===============end===============\n‖);
20. }

Aha, see the difference? Now, the code is more laconic, and the output format is easier to change, you just
need to rewrite the trace statement in the function if you want to change to output format.

For example, if you want to change the output format to the previous one, you just need to modify the
statement:

1. trace(i + ―:‖ + subjectArray[i]);

into:

1. trace(subjectArray[i]);

then, you can get what you want.

With function, eh, you also can call it subroutine; your can reduce the cost of developing or maintaining your
program, especially for large program, while increasing its quality and reliability.

OK, another question is here.

What’s function?

Maybe you’ll quickly remember the concepts of function you learned in your math course when we mention
function here. Let’s do some review now J

In the mathematics, the function is often defined as:


1. f(x) = 2x

or something like that.

After we define the function, f(x), we can know that:

1. f(1) = 2
2. f(2) = 4

That means for the some input, the function has a corresponding output, this is the determinacy of function.
And, it’s totally the same in programming languages.

For example, if we define the following function in ActionScript.

1. function multipleByTwo(someValue:int):int {
2. return someValue << 1;
3. }

Then, the behavior of this function, multipleByTwo is known to us. If you pass 1 as the parameter into this
function, you will get 2, pass 2, you will get 4. You won’t get 5 if you pass 3, that’s the property of function,
determinacy.

Maybe, you’ll say what if I define a function with random output, and then the function is not a deterministic
one. Eh, in this situation, the function is also determinate, and we all know the output of your function is
random J

So, the determinacy of function is mostly about its behavior, which means what you want to do with that
function.

In other words, function is use for carry out specific tasks.

When you notice that some code can be organize to a function unit, and maybe it’ll be reusable in the future.
Then you can define that code block as a function.

After you define a function, you just need to know its behavior and ignore the internal structure of the
function. You can consider the function as a black box, when you put something in, you’ll get something out.

Remember the trace function? We don’t know the internal structure of this amazing function, but we can use
it as we want, that’s the power of function.

So, function is a block of code, the behavior is deterministic, use for carry out specific task.
Beginning ActionScript 3.0 – Define Functions
Continue with the previous section. After we know what function is, maybe we need to know another thing
when we calling the functions, the program flow.

Program Flow

Function has another name, subroutine. Maybe this name is from the structural programming. And this
name indicates something with the program flow.

Let’s go back to the example code.

When the program flow reaches the printScore(math), the program flow will jumps to the entry of printScore
function. After executing all the statements in the printScore function, the program flow will return to the next
statement in the main program,

1. trace(―============History=============‖).

So, you see, when the program flow meets a function, then the program flow will jump to the function entry
and execute the function, after executing all the statements in the function block, the program flow jump
back to the main program. In such a case, the function is just like a small program, so you can call it
subroutine.

After the program flow, let’s move to another question, how to define your own function.

Define functions

OK, let’s focus on the function printScore.

1. function printScore(subjectArray:Array):void {
2.
3. for( var i:int = 0; i < subjectArray.length; i++) {
4. trace(i + ―:‖ + subjectArray[i]);
5. }
6.
7. trace(‖===============end===============\n‖);
8. }

st
The 1 row is function declaration; let’s explain them one by one: function is a keyword, the beginning of
function declaration; printScore is the function name, you can consider it as a identifier; followed the function
name is parenthesis, inside the parenthesis is the parameters’ declaration, here is ―subjectArray:Array‖,
which means only one parameter here, and its name is subjectArray with typed Array; then follow by a colon
and a type keyword, ―: void‖, the type keyword illustrates the return type of this function, here is ―void‖; at the
end of this row is a bracket, the beginning of the code block.

nd th
The 2 to the 5 row is the code block. The actual work is done here.

th
The 6 row is just a bracket, indicating the end of the function definition.

So, the general form of function definition can be described as:

1. function function_name(parameter list) : return type {


2. // code block
3. return someValue;
4. }

As you see, there four factors included in function.

1. Function name. Function name is an identifier, so you should name your function with the rules of
identifier. Remember, you can’t use the same identifier in the same scope, so does function. In addition,
ActionScript doesn’t support overload mechanism semantically, if you’ve any experience about C++ or java,
forget the overload in ActionScript.
2. Parameters. The parameters are all included with the parenthesis, use comma to separate each
parameter. And you need to designate each parameter’s type. If you don’t need to use any parameter, you
can keep the parameter list empty.

3. Function body. All the statements should be included with the brackets. When you call the function, these
statements will be executed.

4. Return value. When you define the function, you can designate the return value’s type. And then you can
use return statement to return a corresponding value inside the function body.

Maybe we don’t need to discuss the function name, because the rules we’ve already learned. And the left
three factors, we’ll discuss later

Beginning ActionScript 3.0 – Function Expressions


In the previous section, we talk about how to declare a function by using the function statements. Today, I’ll
show you another way to declare the functions

Function expressions

The second way to declare a function is to use an assignment statement with a function expression, which is
also sometimes called a function literal or an anonymous function. This is a more verbose method that is
widely used in earlier versions of ActionScript.

Code speaks louder; let’s rewrite the printScore example by the function expression.

1. var math:Array = [70, 80, 65, 90, 85, 100];


2. var history:Array = [90, 89, 92, 82, 78, 95];
3. var music:Array = [72, 75, 89, 92, 65, 79];
4.
5. trace(‖============Mathematics==========‖);
6. printScore(math);
7. trace(‖============History==========‖);
8.
9. printScore(history);
10. trace(‖============Music==========‖);
11.
12. printScore(music);
13.
14. var printScore:Function = function (subjectArray:Array):void {
15. for( var i:int = 0; i < subjectArray.length; i++) {
16. trace(i + ―:‖ + subjectArray[i]);
17. }
18.
19. trace(‖===============end===============\n‖);
20. }

If you try to run the code, you’ll find out that there is an error. Eh, still remember the hoisting mechanism?
Yeah, the code above is equals to the following one:

1. var math:Array = [70, 80, 65, 90, 85, 100];


2. ……
3. var printScore:Function;
4. trace(‖============Mathematics==========‖);
5. printScore(math);
6. ..….
7.
8. printScore = function (subjectArray:Array):void {
9. …….
10. }

That means we just declare the printScore, and the printScore has no definition. So, the solution is place the
definition before the function calling statement.

Now, we have a correct version of function expression. And let’s turn to the grammar of function expression.

1. var printScore:Function = function (subjectArray:Array):void {


2. // function body
3. }
You can take the definition into three parts.

1. Declare a Function type variable. Eh, the left side of the assignment statement.

The form is:

1. var function_name: Function.

Note: you should use Function, not function here. Function is a complex value type, function is a keyword.

2. Define the anonymous function, the form is similar to the function statements, just ignore the function
name. So, you can call function expression as anonymous function.

The form is:

1. function (parameter list) : return_type {


2. //function body
3. }

Note: actually, you can write the function name after the keyword function, but you can’t access the function
through the function name directly.

You can try the following code:

1. var yourFunc:Function = function myFunc(someValue:int):void {


2. trace(someValue);
3. }
4.
5. trace(yourFunc(1));
6. trace(myFunc(1));

You can find that you can’t access the function through the name, myFunc. So, you’d better keep the
function anonymous.

3. Assign the anonymous function to the Function type variable. Just a simple assignment statement.

Combine the three parts together; you can get the general form:

1. var function_name: Function = function (parameter list) : return_type {


2. //function body
3. }
In general, the function expression is equals to define an anonymous function, and then assign it to a
Function type variable.

Actually, you can pass a function statement to the Function type variable if you want, and function is object
in ActionScript.

Beginning ActionScript 3.0 – Calling Functions


Question piled upon a question. After we know how to define the functions, we need to know how to use it.

Calling functions

Remember the identifier that we declare in the function statement? Now, you can use the identifier to call the
function.

In ActionScript, you call a function by using its identifier followed by the parentheses operator (()). You use
the parentheses operator to enclose any function parameters you want to send to the function.

Turn back to our example code, and focus on the center section.

1. trace(‖============Mathematics==========‖);
2. printScore(math);
3.
4. trace(‖============History==========‖);
5. printScore(history);
6.
7. trace(‖============Music==========‖);
8. printScore(music);

In this code, we use the printScore() three times with different parameters, the first time is math, then history
and the third is music.

The statement:

1. printScore(math);

means we call the printScore function here, and pass the math variable as parameter to the printScore
function.

After you know how to call the functions in your code, there is also something you need to notice when you
call the function.
The first thing is keep the number of parameters the same with the function definition. That means if you
declare one parameter, you should pass one parameter when you call the function. If you use two or more
parameters, or you don’t pass any parameters, you’ll get an error from the compiler.

For example, if we call the printScore function without parameters, we’ll get the following result.

The second thing is about the data type.

Suppose we define a function to join two strings like the following:

1. function concat(stringA:String, stringB:String):String {


2. return stringA+stringB;
3. }

Now, we declare two formal parameters, stringA and stringB, and both of them are String type. So, if we use
the following calling statement:

1. concate(1,2);

we’ll get compiler errors.

Because, we use type int values inside the calling statements, while the function definition says they should
be String type. So, when you calling functions, remember use the same type with the formal parameters.

In this example, we can change into:

1. concate(‖1″,‖2″)

The third one is about the order.


Eh, when you declare two or more formal parameters inside your function, please remember the order,
which means when you using the calling statements you should keep the parameters the same order with
the definition.

For example, if you declare a function like this:

1. function concate(integerA:int, stringB:String):String {


2. return integerA.toString()+stringB;
3. }

Then, in the calling statement, you should keep the parameters in order, type int should be first, followed by
the string type value.

1. concate(1,‖2″)

Remember, the compiler is not so smart. The compiler will check the parameters one by one. So, you need
to keep the same number, the same type, and the same order J

Beginning ActionScript 3.0 – Parameter Passing


OK, after some talking about the parameters, let’s go a little deeper with the parameters. This section is
Complex value

In the printScore function, we declare a variable named subjectArray with Array type as parameter.

1. function printScore(subjectArray:Array)…

Here, the subjectArray is called formal parameter. All the variables appear in the parenthesis are formal
parameters.

In the calling statement, such as:

1. printScore(math);

or

1. printScore(music);

The ―math‖ or ―music‖ here is called actual parameter.

We’ve already know that when we call the functions, the program flow will jump out from the current state
into the function entry. Before the program flow wants to jump to the function entry, the runtime environment
will allocate the space in the memory for the function execution. Eh, the space can be use for save the
actual parameter, return address (often points to the next statement after function calling statement) and so
on.

Let’s focus on the parameters, before calling the function, printScore(math), the memory layout maybe as
follows:

Then, the program flow meets the function calling statement, so the runtime environment allocate the space
for the function execution, then the actual parameter, math, will be push into the function stack. Eh, to be
exactly, the value of math, the reference of the Array will be push into the stack, and this reference will
became the value of the formal parameter.

So, the memory layout will be:


Now, you should know that we use the subjectArray in the function outputs the content of math Array.

1. for( var i:int = 0; i < subjectArray.length; i++) {


2. trace(i + ―:‖ + subjectArray[i]);
3. }

Primitive value

OK, show you another example now.

1. function swap(a:int, b:int):void {


2.
3. a = a^b;
4. b = a^b;
5. a = a^b;
6.
7. trace(‖inside the functoin:‖);
8. trace(‖a : ‖ + a);
9. trace(‖b : ‖ + b);
10. }
11.
12. var numberA:int = 1;
13. var numberB:int = 2;
14.
15. swap(numberA, numberB);
16.
17. trace(‖outside the function‖);
18. trace(‖numberA : ‖ + numberA);
19. trace(‖numberB : ‖ + numberB);

We define a function for swapping the values of two integers named swap. Then we define two int type
value, numberA and numberB, and call the function with numberA and numberB. Further more, we use trace
statement to output the values inside the function and after the function execution.

Eh, guess the output J

At last the value of numberA is 2, or not? And the value of numberB is 1, or not?

Let’s see the output.

Wow, it seems that the values of the formal parameters did changed, while the values of numberA and
numberB haven’t got changed.

According to our conclusion above, the formal parameter refers to the same value as the actual parameter.
But in this case, it seems not.

What’s the problem?

Actually, that’s all because the int type is a primitive type. Still remember our discussion about the difference
about the primitive value and complex value?

When we pass the numberA and numberB into the swap function, the formal parameter ―a‖ refers to the
same value object of numberA refers to, and so does ―b‖ and numberB. But, when you change the value of
―a‖, then ―a‖ refers to another value object, no longer refers to the value object of numberA refers to. So, you
change the value of ―a‖ or ―b‖ won’t affect the value of numberA or numberB.
And for the complex value, you should know the reason, isn’t it?

Conclusion

Someone says for the primitive value, you can consider the parameters are passing by value; for the
complex value, you can consider the parameters are passing by reference. Passing by value or reference is
a compiler mechanism.

If you know the mechanism of passing by value or reference, remember it, and you don’t need to read the
following text. if not, the following text may helps you.

When calling the functions, we can simply consider that the actual parameter takes the place of formal
parameter.

For example, when we use

1. printScore(math);

we can consider that there is an assignment statement like:

1. subjectArray = math;

Then, the formal parameter subjectArray is refers to the actual parameter math. If you change the content in
subjectArray, the math Array will also be affected.

If you use the calling statement:

1. swap(numberA, numberB),

There still exist the assignments:

1. a = numberA;
2. b = numberB;

When you do some operations on a or b, and want to change the value of a or b, numberA or numberB
won’t be affected, due to the mechanism of storing the primitive value object in ActionScript.

My suggestion is that, you just need to remember there exist assignments when you calling the function.
The difference between primitive value and complex value is due to the different storing mechanisms of
different type.

about the mechanism of passing the parameters.


Beginning ActionScript 3.0 – Default Parameter Values

After the talking about how to define the functions, and calling them, we are going to talk about the
parameters. And today’s topic is about the default parameter values.

Default parameter values

In some other programming, you can designate the default values to some parameters so that when you call
the functions, you can ignore the parameters which have default values, and the parameters will use the
default values inside the function.

This mechanism is also supported by ActionScript 3.0.

In ActionScript 3.0, you can declare default parameter values for a function. If a call to a function with default
parameter values omits a parameter with default values, the value specified in the function definition for that
parameter is used. All parameters with default values must be placed at the end of the parameter list. The
values assigned as default values must be compile-time constants. The existence of a default value for a
parameter effectively makes that parameter an optional parameter. A parameter without a default value is
considered a required parameter.

For example, we can define the function in this way:

1. function sayHello(somebody:String = ―world‖):void {


2. trace(‖hello, ―+somebody);
3. }

And we can call the function with or with the parameter, such as:

1. sayHello();
2. sayHello(‖ntt.cc‖);

And the output will be:


When you using the default values with formal parameters, you should remember that the default values
should be known in the compile-time, and the parameter with default values should be placed at the end of
the parameter list.

So, if you using the default values this way:

1. function sayHello(somebody:String = ―world‖, someValue:int):void {


2. trace(‖hello, ―+somebody);
3. }

You’ll get a compiler error.

And this way:

1. function getRandomNumber(randomNumber:Number = Math.random()):Number {


2. return randomNumber;
3. }
4. trace(getRandomNumber());

also won’t work.

Because the function Math.random() can’t be determined at the compile-time, it lies on the machine time.

If you want to return the random number inside your function, you can change your function into:

1. function getRandomNumber():Number {
2. return Math.random();
3. }
4.
5. trace(getRandomNumber());

All the return values of function are not compile-time constants. So, don’t use this kind of default value.
Another thing you need to notice is that, when you have two or more parameters with default values, once
one of them are designated, the other parameters before it should be designated too.

Suppose we define a function like follows:

1. function traceNumber(x:int, y:int = 2, z:int = 3):void {


2. trace(x, y, z);
3. }

Of course, we can call the function by this statement:

1. traceNumber(1);

but we can’t use the following statement:

1. traceNumber(1, ,4);

You should designate the second parameter here.

Beginning ActionScript 3.0 – More About Parameters


Besides the default parameters, there are still some thing you need to know about the parameters in
ActionScript 3.0, the Arguments object and the …(rest) parameter.

Arguments object

In last section, we said that when calling the functions we should use the same number of parameters with
our function declaration. Of course, this is true, but it’s only for the compiler in strict mode. In fact, you can
pass more parameters than the defined parameters, if you want to do this, you should use the compiler
mode into standard mode.

If you’re using flash cs3, you can uncheck the strict mode to use the standard mode.
Now, take a look at the following code.

1. function argumentObjectTest(someValue:int):void {
2. for(var i:int = 0; i < arguments.length; i++)
3. trace(arguments[i]);
4. trace(arguments.callee.toString());
5. }
6.
7. argumentObjectTest(1,2,3);

In the above code, we define a function with one formal parameter, while in the main program we call the
function and pass three parameters. And the result will be:

So, from the result, you may know that actually we can get all the parameters passed into the function by
using the argument object.

When parameters are passed to a function, you can use the arguments object to access information about
the parameters passed to your function. The arguments object is an array that includes all the parameters
passed to the function. The arguments.length property reports the number of parameters passed to the
function. The arguments.callee property provides a reference to the function itself, which is useful for
recursive calls to, and this property will be discussed with the recursion.

Note: The arguments object is not available if any parameter is named arguments or if you use the … (rest)

If you don’t need the callee property of arguments object, you can use another parameter, the … (rest)
parameter, instead of using the arguments object.

The …(rest) parameter

ActionScript 3.0 introduces a new parameter declaration called the … (rest) parameter. This parameter
allows you to specify an array parameter that accepts any number of comma- delimited arguments.

A short example is as follows:

1. function restParameterTest(…args):void {
2. for(var i:int = 0; i < args.length; i++)
3. trace(args[i]);
4. }
5.
6. restParameterTest(1,2,3);

and the output is:

As you see, we use args to name the parameter here; in fact, the parameter can have any name that is not
a reserved word.

If you want to use some fixed parameters with the rest parameters, you should place the rest parameter
declaration at last. And the fixed parameters will not be included in the rest parameter array.

Change the code into follows:

1. function restParameterTest(someValue:int, …args):void {


2. for(var i:int = 0; i < args.length; i++)
3. trace(args[i]);
4. }
5.
6. restParameterTest(1,2,3);

You can see the output will be:

When you use this parameter will make the arguments object unavailable.

1. function restParameterTest(someValue:int, …args):void {


2. for(var i:int = 0; i < arguments.length; i++)
3. trace(arguments[i]);
4. }
5.
6. restParameterTest(1,2,3);

Try to compile this code; you will get an error like this:

So, you can’t use the rest parameter with the arguments object.

My suggestion is, use the rest parameter instead of the arguments object if you don’t need the callee
property, because you can use the rest parameter not only in the standard mode, but also in the strict mode.

Anda mungkin juga menyukai