Chapter 4. ActionScript
ActionScript is the programming language that you can use along with MXML to create sophisticated Flex applications. While MXML is an important part of a Flex application, it is mostly used for creating the user interface, and it can go only so far in creating a complete application. For data models and sophisticated client-side business logic, you’ll need to use ActionScript as well.
Flex applications require ActionScript 3.0, which represents a significant maturation from earlier versions of the language. ActionScript 3.0 is compliant with the ECMA-262 specification and leverages parts of the pending ECMAScript Edition 4 specification. ActionScript 3.0 supports a wide range of features including formalized classes, interfaces, and packages, runtime exception handling, runtime data types, reflection, regular expressions, E4X (XML), and more.
ActionScript is a standards-based, object-oriented language. Since ActionScript is an object-oriented language it can be viewed as a collection of APIs generally in the form of classes. There are three tiers of ActionScript APIs:
- Flash Player APIs
These APIs are part of the Flash Player itself, and they run natively in that runtime environment. Flash Player APIs consist of core classes such as
String
,Number
,Date
, andArray
as well as Flash Player-specific classes such asDisplayObject
,URLLoader
,NetConnection
,Video
, andSound
.- Flex framework APIs
These are the APIs that make up the Flex framework itself. The Flex framework is written in ActionScript, so it leverages the lower-level Flash Player APIs. The Flex framework is effectively a layer on top of the Flash Player APIs. The Flex framework APIs consist of all the Flex containers (
Application
,VBox
, etc.), controls (Button
,TextInput
, etc.), and other assorted data, manager, and utility classes that are discussed throughout much of this book.- Custom APIs
These APIs are for the classes you build for use in custom applications. Custom classes can use Flash Player APIs as well as the Flex framework APIs.
The APIs that comprise the Flash Player are far too large a category to attempt to discuss in this chapter, and in fact there are books spanning many hundreds of pages that still can’t cover all of the Flash Player APIs. Our assumption in this book is that you are either already basically familiar with the Flash Player APIs or you are also reading a companion reference specific to Flash Player APIs. Most ActionScript 3.0 books focus primarily on the Flash Player APIs. You will most likely find that the Flex documentation API reference is quite helpful in this regard.
Tip
Much of this book is dedicated to the Flex framework APIs, via either ActionScript or MXML. For that reason, this chapter doesn’t focus on the Flex framework APIs.
ActionScript 3.0 is an object-oriented language, which means that in one form or another, the ActionScript code you write is part of a class. This book assumes you are already familiar with basic object-oriented programming concepts. It is not our intention to attempt to teach object-oriented theory in this chapter. Yet you will need to have a fundamental understanding of object-oriented concepts to make the most of this chapter. You can find a good introduction to object-oriented concepts at http://en.wikipedia.org/wiki/Object-oriented.
ActionScript is an important and essential part of Flex applications. In fact, ActionScript is the foundation upon which the entire Flex framework is written. This chapter teaches you the important fundamental concepts about ActionScript, including the relationship between MXML and ActionScript, ActionScript syntax, events, error handling, XML, and reflection.
Using ActionScript
When you want to use ActionScript within Flex, you have four basic options for where to place the code:
Inline within MXML tags
Nested within MXML tags
In MXML scripts
Within ActionScript classes
The preceding lists the techniques for working with ActionScript code, from the simplest to the most complex form. We’ll look at each of these techniques in the following sections.
Inline ActionScript
Inline ActionScript appears within MXML tags. Believe it or not, you’ve already seen several examples of this in Chapter 3. Inline event handling and data binding using curly brace syntax necessarily uses basic ActionScript. The following example uses ActionScript to display an alert dialog box when the user clicks on a button:
<mx:Button id="alertButton" label="Show Alert" click="mx.controls.Alert.show('Example')" />
In this example, the text assigned to the click
event handler attribute is ActionScript code, which calls a show( )
method of an ActionScript class called Alert
.
The next example uses data binding:
<mx:VBox> <mx:TextInput id="input" /> <mx:Text id="output" text="{input.text}" /> </mx:VBox>
This example uses the ActionScript expression input.text
to evaluate the text
property value for the input
object (the text input control).
Inline data binding represents the most limited use of ActionScript, because it can evaluate only one expression. For instance, the preceding example evaluates the expression input.text
. You could use a more complex expression, such as the following:
<mx:VBox> <mx:TextInput id="input" /> <mx:Text id="output" text="{'User input: ' + input.text}" /> </mx:VBox>
This example concatenates the string User input:
with the user input from the text input control. You can also create even more complex expressions using inline data binding.
Inline event handlers allow you to write more complex ActionScript that can consist of several statements. ActionScript statements generally end with semicolons. The following example illustrates a button with slightly more complex event handler code, consisting of two expressions:
<mx:Button id="alertButton" label="Show Alert" click="mx.controls.Alert. show('Example');alertButton.x += 40;" />
This example first displays an alert dialog box. It then moves the button to the right by 40 pixels. Although you can string together many statements (as in this example), it is very uncommon. It’s not difficult to understand why this would be. Rather simply: the code is difficult to read and manage when you try to use several inline statements in that fashion. If an event handler needs to run several statements, it is far more common to simply call a function. We’ll look more at functions in the next section, and then later in the chapter, in the "Methods" section.
Nested ActionScript
You also can nest ActionScript code within MXML tags. Just as you can nest values for most properties you can nest the values (ActionScript) for event handlers. You must place the code within a CDATA
block. Here’s an example:
<mx:Button> <mx:click> <![CDATA[ mx.controls.Alert.show("Example"); ]]> </mx:click> </mx:Button>
MXML Scripts
The second way to add ActionScript code to an application is to place it within an MXML script. An MXML script appears in an MXML document within a Script
element:
<mx:Script> </mx:Script>
Since ActionScript code may use special characters otherwise interpreted by the MXML compiler, you must place ActionScript code within Script
tags and also within a CDATA
block, as in the following example:
<mx:Script><![CDATA[ import mx.controls.Alert; private function example( ):void { Alert.show("Example"); } ]]> </mx:Script>
You can optionally place ActionScript code blocks in separate files, and you can embed them in a script block using the source
attribute of a Script
tag:
<mx:Script source="code.as" />
Within MXML scripts, you can import classes and declare properties and methods. We discuss each of these in more detail in the "Understanding ActionScript Syntax" section, later in this chapter.
Classes
Classes are the most sophisticated and powerful use of ActionScript. Although it’s not wrong to use inline code and MXML scripts, it’s generally advisable to place the majority of ActionScript code within ActionScript classes.
ActionScript class code exists within separate documents, apart from the MXML application and component documents. ActionScript class files are text files that use the file extension .as. We’ll talk more about creating classes later in this chapter, in the "Declaring Classes" section.
MXML and ActionScript Correlations
MXML is a powerful way to simplify the creation of user interfaces. In most cases, it is far better to use MXML for layout than to attempt the same thing with ActionScript. ActionScript is far better suited for business logic and data models. However, MXML and ActionScript are not really so different. In fact, MXML actually gets converted to ActionScript during compilation, and the MXML structure can be understood in terms of an ActionScript class. This can be useful because it allows you to better understand how MXML works and how it relates to ActionScript.
When you use an MXML tag to create a component instance, it is the equivalent to calling the component class’s constructor as part of a new statement. For example, the following MXML tag creates a new button:
<mx:Button id="button" />
That is equivalent to the following piece of ActionScript code:
var button:Button = new Button( );
If you assign property values using MXML tag attributes, that’s equivalent to setting the object properties via ActionScript. For example, the following creates a button
and sets the label
:
<mx:Button id="button" label="Click" />
The following code is the ActionScript equivalent:
var button:Button = new Button( ); button.label = "Click";
This demonstrates that MXML component tags correspond to ActionScript classes. Furthermore, MXML documents themselves are essentially ActionScript classes, simply authored in a different syntax. This is an extremely important point to understand. An application document is a class that extends the mx.core.Application
, and component documents are classes that extend the corresponding component class (e.g., mx.containers.VBox
).
MXML simplifies writing these classes because the MXML tags automatically translate into many lines of ActionScript code that handle important Flex framework tasks such as initialization, layout rules, and so forth.
When you create components with IDs in an MXML document, those are really properties of the class formed by the document. For example, the following creates a new class that extends mx.core.Application
and creates one property called Button
of type mx.controls.Button
:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:Button id="Button" /> </mx:Application>
The preceding example is essentially the same as the following ActionScript class:
package { import mx.core.Application; import mx.controls.Button; public class Example extends Application { internal var button:Button; public function Example( ) { super( ); button = new Button( ); addChild(button); } } }
Tip
The preceding example is an over-simplification. The actual equivalent ActionScript class would be more complex due to initialization requirements of Flex framework components. However, it illustrates the basic relationship between MXML and ActionScript.
When code is placed in an MXML script, it is equivalent to placing code within a class body. Variable declarations within MXML scripts are treated as properties of the class, and functions are methods of the class. This means that the rules that apply to writing pure ActionScript classes also apply to MXML scripts. For this reason, we’ll focus almost exclusively on writing pure ActionScript class code throughout the remainder of this chapter. However, note that you can apply what you learn to MXML scripts as well.
Understanding ActionScript Syntax
Whether you’re writing ActionScript code inline, in an MXML script, or in a class, you’ll need to understand its basic syntax. The following sections look at the basic elements of ActionScript, such as class syntax, variables, statements, expressions, functions, and objects.
Understanding Packages
The majority of classes are organized into structures called packages. To understand most of ActionScript, you must understand what packages are and how you can work with them.
A package groups together classes so that you can ensure uniqueness of scope. For example, you can have only one Button
class within a scope. If you tried to declare two Button
classes in the same scope, there would be a conflict; the compiler wouldn’t know which one to use.
A package allows you to create several classes with the same name by placing them in different scopes. For example, the Button
class that’s part of the Flex framework (i.e., the button UI component) exists within a package called mx.controls
. When a class is placed within a package, it has what’s called a fully qualified class name. Therefore, the fully qualified class name for Button
is mx.controls.Button
. That ensures that if you want to create another Button
class in a different package, you can do so without conflicting with mx.controls.Button
. For example, mx.controls.Button
and com.example.ui.Button
(a fictitious class) could exist within the same application without causing a problem.
When classes are in packages, it can be quite cumbersome to have to refer to a class by its fully qualified name. For example, if you want to declare a Button
variable, you have to use the following code if you wish to use the fully qualified class name:
var button:mx.controls.Button;
And if you wanted to use the constructor, you’d have to use the following code:
button = new mx.controls.Button( );
Obviously, it’s much more convenient to use the shorthand form of a class name (i.e., Button
). ActionScript allows you to reference a class by the shorthand notation if you first add an import
statement. An import
statement tells the compiler that you can refer to the class by its shorthand notation from that point forward. The following is an import
statement for the Button
class:
import mx.controls.Button;
You can simply refer to Button
as such from that point forward.
Tip
If you import two Button
classes (from different packages) in the same class, you must still refer to them using their fully qualified class names within that class.
Declaring Classes
Next, let’s look at the basic syntax and structure of a class. At a minimum, all ActionScript 3.0 classes consist of the following elements:
Class package declaration
Class declaration
Additionally, classes almost always also have import
statements.
Creating class files
Each class must be defined in its own file. (There are a few unique exceptions, but in most practical cases, a class must be defined in its own file.) The name of the file must be the same as the name of the class it contains, and the file must use the .as file extension. For instance, if you want to define an Example
class, you must create a file named Example.as.
Package declarations
The syntax for all ActionScript 3.0 classes begins with a package declaration. As discussed earlier in this chapter, packages are used to organize classes. A package name in ActionScript corresponds to the directory structure within which the ActionScript file is stored. Each directory and subdirectory is delimited by a dot (.
) in a package name. For example, if a class is stored in the example subdirectory of a com directory, the package name would be com.example
. A class’s package declaration uses the package
keyword followed by the package name. Opening and closing curly braces, which contain any import
statements and class declarations, follow the package
declaration. The following package
declaration says that the enclosed class exists within the com.example
package. This also means that the file must exist within a com/example directory relative to one of the source path directories:
package com.example { // Import statements go here. // Class declaration goes here. }
Tip
It’s considered a best practice to place all class files within packages with the possible exception of main class files when creating ActionScript 3.0-only (non-Flex) applications.
Import statements
As noted earlier, import
statements should appear within the package
declaration, but not within the class declaration. (Technically, import
statements can be placed anywhere, but by convention, they should be placed within the package
declaration, but not in the class declaration.)You must import
any and all classes you intend to use. ActionScript 3.0 classes don’t automatically import classes. The following example imports the URLLoader
and URLRequest
classes from the Flash Player API:
package com.example { import flash.net.URLLoader; import flash.net.URLRequest; // Class declaration goes here. }
Class declaration
All public ActionScript 3.0 classes placed within package
declarations must be declared using the public
keyword, followed by the class
keyword and the name of the class. Opening and closing curly braces then follow, within which you place the class definition. Class names always start with initial capital letters by convention. The following example declares an Example
class in the com.example
package:
package com.example { import flash.net.URLLoader; import flash.net.URLRequest; public class Example { // Class code goes here. } }
Variables and Properties
A variable is a named element you can use to store data or a reference to data. You can assign values to and read values from a variable.
When you want to work with a variable, the first thing you’ll need to do is declare it. Declaring a variable allocates memory for it and tells the application that the variable exists. You can declare a variable using the var
keyword as follows:
var variableName;
The var
keyword is followed by the name of the variable. Variable names in ActionScript are arbitrary, but they must follow a few simple rules:
The variable name can consist only of letters, numbers, dollar signs, and underscores.
The variable name must not start with a number.
By convention, all ActionScript variables use initial lowercase characters rather than initial uppercase characters. The following declares a variable called userName
:
var userName;
Although you can declare a variable without a data type, it’s always recommended that you declare a variable with a data type. You can add a data type to the variable declaration using post-colon syntax as follows:
varvariableName
:DataType
;
The data type determines the kind of data you can store in the variable. There are many data types, ranging from simple strings and numbers to reference types (such as arrays), and all the types defined by the Flex framework (e.g., TextInput
, Button
, etc.). There are far too many data types to list comprehensively here (especially since you can define custom data types). However, some of the most common core data types are String
, Number
, int
, uint
, Boolean
, Date
, and Array
, as defined in Table 4-1.
Data type | Description |
| One or more characters, including all Unicode characters |
| Any numeric value, including floating-point numbers |
| Positive and negative integers and 0 |
| Positive integers and 0 |
| True or false |
| The date and time |
| An index-ordered collection of data |
When a variable is declared with a data type, you’ll receive errors if you attempt to assign an invalid value to the variable. Flex applications provide both compile-time and runtime type checking.
The following example declares the userName
variable with the data type String
:
var userName:String;
Once you’ve declared a variable, the next thing to do is assign values using an assignment operator (an equals sign), as in the following example:
userName = "Flex User";
You can also combine a declaration and assignment into one line:
var userName:String = "Flex User";
When you want to retrieve a value from a variable, you simply reference the variable in a statement or expression that expects that type of value. The following example assigns the value from the userName
variable to the text
property of a text
input component:
textInput.text = userName;
Variables are placed within class methods (find more on method syntax in the “Methods section, later in this chapter). Variables declared outside of methods are called properties, and they are scoped to the entire class. In most respects, variables and properties are the same. However, there is one key difference that shows up syntactically, which is simply a matter of scope. Here we describe the contrast between variable and property scope:
All variables declared within methods are scoped exclusively to those methods. That means you cannot reference a variable outside the method in which it is declared.
Properties, on the other hand, have much greater scope. At a minimum, a property is accessible within the entire class. However, you can also opt to allow the property to be accessible outside the class with various settings called modifiers.
Classes define properties using quite a few possible modifiers. A property can be one of the following:
public
The
public
modifier means the property is accessible outside the class (e.g., from an instance of the class).private
The
private
modifier makes the property accessible only within the class.protected
The
protected
modifier makes the property accessible only within the class and its subclasses.internal
The
internal
modifier makes the property accessible only within the package.
Practically, you should always declare properties as private
or protected
. It is not a good idea to declare public
properties because a class should always manage its state (the values of its properties). internal
properties are a bad idea for the same reason.
You can declare properties in much the same way as you would declare variables:using the var
keyword. In addition, a property name must follow the same rules as variable names. A common convention (and one used by this book) names private
and protected
properties with an initial underscore (_
) to help distinguish them from local variables declared within methods. The following example declares a private
property called _loader
of type URLLoader
:
package com.example { import flash.net.URLLoader; import flash.net.URLRequest; public class Example { private var _loader:URLLoader; } }
In addition to the public
, private
, protected
, and internal
modifiers, you can also combine these modifiers with the static
modifier. The static
modifier says that the property is directly accessible from the class rather than from instances. Static modifiers are used for many purposes, including design patterns such as the Singleton pattern. The following example adds a static private
property called _instance
of type Example
:
package com.example { import flash.net.URLLoader; import flash.net.URLRequest; public class Example { private var _loader:URLLoader; static private var _instance:Example; } }
A concept related to properties is that of the constant. A constant is a container for data, much like a variable/property except that once it has a value, you cannot change the value (hence the name, constant). You’ve likely seen constants in the Flash Player and Flex framework API. A few examples of constants are Event.COMPLETE
, MouseEvent.CLICK
, TimerEvent.TIMER
, and Math.PI
. Although not a requirement, most constants are declared as static
, and most are also declared as public
(unlike properties, constants aren’t part of a class’s state and can therefore be declared public
). To declare a constant, use the const
keyword rather than var
. By convention, constant names are all uppercase, as shown here:
package com.example { import flash.net.URLLoader; import flash.net.URLRequest; public class Example { private var _loader:URLLoader; static private var _instance:Example; static public const TEST:String = "test constant"; } }
Methods
A method is a way to group together statements, give that group a name, and defer the execution of those statements until the method is called by its name. All method definitions must be placed within a class body, and they use the function
keyword followed by the name of the method. Following the method name is a pair of parentheses enclosing any parameters that the method might accept. That is followed by a colon and the return type of the method. If the function does not return a value, the return type is declared as void. Following the return type declaration is the function definition enclosed in opening and closing curly braces. The following is a declaration for a function called test( )
:
function test( ):void { }
The test( )
method is declared so that it does not expect any parameters, and it does not expect to return a value. Currently, the test( )
method doesn’t do anything either. Next, add a few statements inside the function
so that it does something:
function test( ):void { var message:String = "function message"; trace(message); }
Tip
The trace( )
function writes text to an output such as a console or logfile. Chapter 17 discusses trace( )
in more detail.
Now the test( )
method declares a variable called message
, assigns a value to it (function message
), and then uses trace( )
to output the value to the console (if debugging).
To call a method, use the method name followed by the function
call operator (the parentheses). For example, if you want to call the test( )
method, you would use the following statement:
test( );
If you want to declare a method so that you can pass it parameters, you must declare the parameters within the parentheses as a comma-delimited list. The parameter declarations consist of the parameter name and post-colon data typing. The following example rewrites test( )
so that it expects two parameters (a
and b
):
function test(a:String, b:String):void { trace("Your message is " + a + " and " + b); }
When you want to call a method with parameters, simply pass the values within the function call operator, as in the following example:
test("one", "two");
ActionScript does not allow overloading. That means you cannot have two methods with the same name but different signatures (different parameter lists). However, ActionScript does allow for rest parameters. Rest parameters allow you to pass zero or more additional parameters of unknown types to a function. You declare a rest parameter using a parameter name preceded immediately by three dots. Within the method you can access the rest parameter values as an array.
Currently, the test( )
example requires exactly two parameters (a
and b
). You cannot pass fewer or more than two parameters. If you want to pass just one parameter (or five parameters), you need a solution that rest parameters provide. The following code rewrites test( )
so that it always requires at least one parameter, but it also allows for zero or more additional parameters. By convention, the rest parameter is called rest
(though you may use arbitrary names for the parameter):
function test(a:String, ...rest):void { var message:String = "Your message is"; for(var i:uint = 0; i < rest.length; i++) { message += " " + rest[i]; } trace(message); }
If you want to return a value from a method you need to do two things: specify the correct return type, and add a return
statement. When you specify a return type, you’ll get both compile-time and runtime checking. A function set to return a String
value must return a string, not a number, date, array, or any other type. A return
statement immediately exits the function and returns the specified value to the expression or statement from which the function was called. The following rewrite of test( )
returns a string:
function test(a:String, ...rest):String { var message:String = "Your message is"; for(var i:uint = 0; i < rest.length; i++) { message += " " + rest[i]; } return message; }
Methods use the same public
, private
, protected
, internal
, and static
modifiers as properties. If you omit the modifiers (as in the preceding examples), Flex assumes the methods are internal
. The following declares two methods, one public
and one public
and static
:
package com.example { import flash.net.URLLoader; import flash.net.URLRequest; public class Example { private var _loader:URLLoader; static private var _instance:Example; static public const TEST:String = "test constant";public function traceMessage(message:String):void { trace("Your message is " + message): } static public function getInstance( ):Example { if(_instance == null) { _instance = new Example( ); } return _instance; } } }
Tip
Unlike properties, it is common and acceptable to declare public methods.
Classes also can and should have a special type of method called a constructor. The constructor method has the following rules:
The method name must be the same as that of the class.
The method must be declared as
public
.The method must not declare a return type or return a value.
The following constructor assigns a new value to the _loader
property:
package com.example { import flash.net.URLLoader; import flash.net.URLRequest; public class Example { private var _loader:URLLoader; static private var _instance:Example; static public const TEST:String = "test constant";public function Example( ) { _loader = new URLLoader( ); } public function traceMessage(message:String):void { trace("Your message is " + message); } static public function getInstance( ):Example { if(_instance == null) { _instance = new Example( ); } return _instance; } } }
There are two additional special method types called: implicit getter and setter methods. These are declared as methods, but they are accessible as though they were public
properties. The method declarations are identical to normal method declarations, except for the following:
Getter methods use the
get
keyword.Setter methods use the
set
keyword.Getter methods must not expect any parameters and must return a value.
Setter methods must expect exactly one parameter and must be declared with a
void
return type.
The following example declares a getter and a setter method, each called sampleProperty
. In this example, a new private
property is declared using the getter and setter methods as accessors. This is not a requirement for getter and setter methods, but it is a common use case:
package com.example { import flash.net.URLLoader; import flash.net.URLRequest; public class Example { private var _loader:URLLoader; static private var _instance:Example; private var _sampleProperty:String; public function get sampleProperty( ):String { return _sampleProperty; } public function set sampleProperty(value:String):void { _sampleProperty = value; } static public const TEST:String = "test constant"; public function Example( ) { _loader = new URLLoader( ); } public function traceMessage(message:String):void { trace("Your message is " + message); } static public function getInstance( ):Example { if(_instance == null) { _instance = new Example( ); } return _instance; } } }
You can call the getter method by using the method name as a property in a context that attempts to read the value. You can call the setter method by using the method name as a property in a context that attempts to write a value. The following example creates an instance of the Example
class, then writes and reads a value to and from the instance using the getter and setter methods:
var example:Example = new Example( ); example.sampleProperty = "A"; // Call the setter, passing it A as a parameter trace(example.sampleProperty); // Call the getter
Expressions
An expression is any ActionScript that can be evaluated. At its simplest, an expression might consist of just one literal value or one variable. More complex expressions combine several values and/or variables using operators. There are many types of operators in ActionScript, ranging from mathematical operators to Boolean operators to bitwise operators. Most operators operate on two operands. For example, the following uses variables as operands in conjunction with a multiplication operator:
unitValue * quantity
Generally, expressions are not used in isolation. For example, the preceding code multiplies the values from two variables, but it does not do anything with that product. That value would typically be used in an assignment statement or as part of a larger expression. Boolean expressions are often used in if
and for
statements, which we’ll look at next.
Statements
Statements are the building blocks of an application. They define the actions and program flow. Statements tell the application to do something. They can consist of variable declarations, assignments, function calls, loops, and conditionals.
You’ve already seen examples of variable declaration statements, as in the following:
var total:Number;
An assignment statement uses the equals sign (=
) to apply the value on the right side to the variable on the left. For example, the following code assigns the product of unitValue
and quantity
to a variable called total
:
total = unitValue * quantity;
A statement can also be a call to a function. The following example calls a trace( )
function, which is a built-in Flash Player function that writes to the console when running a debug version of an application in the debug player:
trace("This is a simple statement.");
So far, you’ll notice that each of the statements ends with a semicolon. All statements of these types should end with semicolons in ActionScript. These types of statements comprise the majority of ActionScript statements. However, there are some statements that do not end in semicolons. Those statements are looping and conditional statements including while
, for
, and if
statements.
Looping statements, such as while
and for
, allow you to loop the execution of a group of statements as long as a condition is met. The following is an example of a while
statement in ActionScript. This statement increments total
as long as total
is less than maxTotal
:
while(total < maxTotal) { total += 5; }
You can use for
statements as a compact way to write common loops. The for
statement syntax is similar to that of the while
statement, except that in place of the one conditional expression, a for
statement uses three expressions: initialization, condition, and update. The following for
statement calls trace( )
five times:
for(var i:int = 0; i < 5; i++) { trace(i); }
Conditional statements use Boolean expressions to make the execution of some statement or statements conditional. The following example adds five to total
if total
is less than maxTotal
:
if(total < maxTotal) { total += 5; }
You can use if
statements on their own as in the preceding example. You can also use if
statements in conjunction with else
clauses. You can use these clauses only as part of an if
statement. If the if
statement conditional expression evaluates to false
, else
clauses that follow are run until one of the conditions evaluates to true
. It is possible to nest conditionals, and by convention the nested if
statement starts on the same line as the else
clause within which it is nested, creating what are often thought of as else if
clauses (though they are technically else
clauses with nested if
statements). The following example adds five to total
if total
is less than maxTotal
; otherwise, the code subtracts five:
if(total < maxTotal) { total += 5; } else { total -= 5; }
The following interjects an else if
clause that tests whether the total
is 20 more than maxTotal
. If so, it subtracts 10; otherwise, it goes to the else
clause:
if(total < maxTotal) { total += 5; } else if(total > maxTotal + 20) { total -= 10; } else { total -= 5; }
Arrays
Arrays are sets of data organized by integer indices or keys. ActionScript defines an Array
type. New arrays are defined using an Array
constructor as part of a new statement (which we’ll talk about in the next section, "Objects“), or using literal notation. The literal notation uses square brackets to create an array. The following creates a new empty array and assigns it to a variable:
var books:Array = [];
You can also populate an array by adding a comma-delimited list of values between the square brackets:
var books:Array = ["Programming Flex 2", "ActionScript 3.0 Cookbook"];
You can access specific elements of the array using array access notation. The following example retrieves the first element from the array (ActionScript arrays are 0-indexed) and displays it in the console (again, if you are debugging the application):
trace(book[0]);
You can also assign values to elements using array access notation, as follows:
book[2] = "Web Services Essentials";
Arrays are objects in ActionScript, and they have methods and properties like most objects. It’s beyond the scope of this book to delve into the Array
API in depth. However, of the Array
API, the length
property and push( )
method are the most commonly used. The length
property returns the number of elements in the array, and it is commonly used with a for
statement to loop through all the elements of an array. The push( )
method allows you to append elements to an array.
ActionScript arrays are not strongly typed. That means you can store any sort of data in an array, even mixed types. Theoretically, you could store numbers, strings, dates, and even other arrays in an array.
ActionScript does not have any formal hashmaps or similar types. ActionScript does have an Object
type, which is the most basic of all object types. Unlike the majority of ActionScript classes the Object
class is dynamic, which means you can add arbitrary properties to Object
instances. Although it is generally better to write data model classes than to store data in Object
instances using arbitrary properties, there are cases when it is useful to use an Object
instance as a hashmap/associative array. The following example creates an Object
instance and assigns several keys and values:
var authorsByBook:Object = new Object( ); authorsByBook["Programming Flex 2"] = "Chafic Kazoun,Joey Lott"; authorsByBook["ActionScript 3.0 Cookbook"] = "Joey Lott,Keith Peters,Darron Schall";
Objects
Objects are composites of state and functionality that you can use as elements within ActionScript code. There are potentially an infinite range of object types, including those from the built-in Flash Player types to Flex framework types to custom types.
An object is an instance of a class, which is a blueprint of sorts. Although there are other mechanisms for creating objects, the most common is to use a new
statement with a constructor. The constructor for a class is a special function that shares the same name as the class. For example, the constructor for the Array
class is called Array
. Like any other functions a constructor may or may not expect parameters. The only way to know whether a particular constructor expects parameters is to consult the API documentation. However, unlike most functions, a constructor must be used as part of a new
statement, and it always creates a new instance of the class. The following example creates a new array using a new
statement:
var books:Array = new Array( );
Objects may have properties and methods depending on the type. Properties are essentially variables associated with an object, and methods are essentially functions associated with the object. You can reference properties and methods of an object in ActionScript using dot-syntax. Dot-syntax uses a dot between the name of the object and the property of the method. The following example uses dot-syntax to call the push( )
method of the array object (the push( )
method appends the value as an array element):
books.push("Programming Flex 2");
The next example uses dot-syntax to reference the length
property of the array object:
trace(books.length);
Inheritance
You can create new classes (called subclasses) that inherit from existing classes (called superclasses). You achieve this using the extends
keyword when declaring the class. The extends
keyword should follow the class name and be followed by the class from which you want to inherit. The following defines class B
, so it inherits from a fictional class, A
:
package com.example { import com.example.A; public class B extends A { } }
ActionScript 3.0 allows a class to inherit from just one superclass. The subclass inherits the entire implementation of the superclass, but it can access only properties and methods declared as public
or protected
. Properties that are declared as private
and methods are never accessible outside a class—not even to subclasses. Classes in the same package can access properties declared as internal
. Consider the class A
and class B
example, if A
is defined as follows:
package com.example { public class A { private var _one:String; protected var _two:String; public function A( ) { initialize( ); } private function initialize( ):void { _one = "one"; _two = "two"; } public function run( ):void { trace("A"); } } }
In this example, B
(which is defined as a subclass of A
) can access _two
and run( )
, but it cannot access _one
or initialize( )
.
If a subclass wants to create its own implementation for a method that it inherits from a superclass, it can do so by overriding it. Normally, a subclass blindly inherits all of the superclass implementation. However, when you override a method, you tell the subclass that it should disregard the inherited implementation and use the overridden implementation instead. To override a method, you must use the override
keyword in the method declaration; the following overrides the run( )
method:
package com.example { import com.example.A; public class B extends A { override public function run( ):void { trace("B"); } } }
When a subclass overrides a superclass method, the subclass method’s signature must be identical to the superclass method’s signature, i.e., the parameters, return type, and access modifier must be the same.
Interfaces
ActionScript 3.0 also allows you to define interfaces. Interfaces allow you to separate the interface from the implementation, which enables greater application flexibility.
Much of what you learned about declaring classes applies to declaring interfaces as well. In fact, it’s easier to list the differences:
Interfaces use the
interface
keyword rather than theclass
keyword.Interfaces cannot declare properties.
Interface methods declare the method signature but not the implementation.
Interfaces declare only the
public
interface for implementing classes, and therefore method signature declarations do not allow for modifiers.
By convention, interface names start with an uppercase I
. The following is an example of an interface:
package com.example { public interface IExample { function a( ):String; function b(one:String, two:uint):void; } }
In the preceding example, interface
says that any implementing class must declare methods a( )
and b( )
using the specified signatures.
You can declare a class so that it implements an interface using the implements
keyword, following the class name or following the superclass name if the class extends a superclass. The following example implements IExample
:
package com.example { import com.example.IExample; public class Example implements IExample { public function Example( ) { } public function a( ):String { return "a"; } public function b(one:String, two:uint):void { trace(one + " " + two); } } }
When a class implements an interface, the compiler verifies that it implements all the required methods. If it doesn’t, the compiler throws an error. A class can implement methods beyond those specified by an interface, but it must always implement at least those methods. A class can also implement more than one interface with a comma-delimited list of interfaces following the implements
keyword.
Handling Events
ActionScript 3.0 and the Flex framework use events to notify and receive notification when things occur. Events occur in response to the user (for example, the user clicks on something), time (timer events), and asynchronous messaging (such as remote procedure calls). Regardless of the cause of an event, nearly all ActionScript events use the same event model.
In MXML (Chapter 3), you saw how to use event handler attributes. In ActionScript, you can handle events by registering listeners. A listener is a function or method that should receive notifications when an event is dispatched. For example, you can register a method to receive a notification when the user clicks a button.
You need at least two elements to register a listener: an object that dispatches events, and a function that listens for events. Objects capable of dispatching events either extend the flash.events.EventDispatcher
class or implement the flash.events.IEventDispatcher
interface. When an object can dispatch events, it has a public addEventListener( )
method that requires at least two parameters; the name of the event for which you want to listen and the function/method that should listen for the event:
object.addEventListener("eventName", listenerFunction);
In most cases, the event names are stored in constants of the corresponding event type class. For example, the click event name is stored in the MouseEvent.CLICK
constant.
The listener function must expect one parameter of type mx.events.Event
or the relevant subclass of Event
. For example, if the object dispatches an event of type MouseEvent
, the listener should accept a MouseEvent
parameter. The event parameter contains information about the event that occurred, including a reference to the object dispatching the event (the target
property of the event object) and the object that most recently bubbled (relayed) the event (the currentTarget
property). (In many cases, the target
and currentTarget
properties reference the same object.) The following example adds an event listener using ActionScript, and when the user clicks the button, the listener displays the event object in an alert dialog box:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="initializeHandler(event)"> <mx:Script> <![CDATA[ import mx.controls.Alert; private function initializeHandler(event:Event):void { button.addEventListener(MouseEvent.CLICK, clickHandler); } private function clickHandler(event:MouseEvent):void { Alert.show(event.toString( )); } ]]> </mx:Script> <mx:Button id="button" /> </mx:Application>
You can also unregister an event listener using the removeEventListener( )
method. This method requires the same parameters as addEventListener( )
. The method unregisters the specified listener function as a listener for the specified event. It is extremely important that you remove event listeners when they are no longer necessary. This includes all cases where you want to remove from memory the object listening for the events. Flash Player will not garbage-collect an object if there are any references to it still in memory. That means that even if an object is no longer used anywhere in the application, except for a reference held by an event dispatcher, it will not be garbage-collected.
The following example removes the event listener added in the previous example:
button.removeEventListener(MouseEvent.CLICK, onClick);
Error Handling
ActionScript 3.0 supports runtime error handling. That means that if and when an error occurs, the application can respond to the error in an elegant fashion rather than simply fail to work without any notification to the user. ActionScript 3.0 uses two types of runtime errors: synchronous and asynchronous.
Handling Synchronous Errors
Synchronous errors occur immediately when trying to execute a statement. You can use try
/catch
/finally
to handle synchronous errors.
When you have some code that may throw runtime errors, surround it with a try
statement:
try { // Code that might throw errors }
You must then include one or more catch
blocks following a try
. If the code in the try
block throws an error, the application attempts to match the error to the catch
blocks in the order in which they appear. Every catch
block must specify the specific type of error that it handles. The application runs the first catch
block that it encounters to see if it matches the type of error thrown. All error types are either flash.errors.Error
types or subclasses of Error
. Therefore, you should try to catch more specific error types first, and more generic types (e.g., Error
) later; for example:
try { // Code that might throw errors } catch (error:IOError) { // Code in case the specific error occurs } catch (error:Error) { // Code in case a non-specific error occurs }
In addition, you can add a finally
clause that runs regardless of whether the try
statement is successful:
try { // Code that might throw errors } catch (error:IOError) { // Code in case the specific error occurs } catch (error:Error) { // Code in case a non-specific error occurs } finally { // Code to run in any case }
Most Flash Player and Flex framework classes use asynchronous errors rather than synchronous errors, so the following example may seem impractical, but it does illustrate the syntax for using try
/catch
. The browse( )
method for a FileReference
object opens a browse dialog box that lets the user select a file from his local filesystem. However, Flash Player can display only one browse dialog box at a time. If you call browse( )
while a browse dialog box is already open, it throws a flash.errors.IOError
type of error. If you don’t handle the error, the user receives a notification in a default error dialog box:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="initializeHandler(event)"> <mx:Script> <![CDATA[ import flash.net.FileReference; private function initializeHandler(event:Event):void { var file:FileReference = new FileReference( ); file.browse( ); file.browse( ); } ]]> </mx:Script> </mx:Application>
The following example rewrites the preceding code using error handling:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="initializeHandler(event)"> <mx:Script> <![CDATA[ import flash.net.FileReference; private function initializeHandler(event:Event):void { var file:FileReference = new FileReference( ); try { file.browse( ); file.browse( ); } catch(error:Error) { errors.text += error + "\n"; } } ]]> </mx:Script> <mx:TextArea id="errors" /> </mx:Application>
Handling Asynchronous Errors
Many objects in ActionScript can potentially throw asynchronous errors. Asynchronous errors are those that occur in response to network operations. For example, if a requested file is not found, the network operation fails asynchronously, and an asynchronous error is thrown. All asynchronous errors are in the form of events, and they use the same event model as standard events. For example, if a URLLoader
object attempts to load data outside the Flash Player security sandbox, it dispatches a securityError
event. The following example illustrates how to handle error events:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="initializeHandler(event)"> <mx:Script> <![CDATA[ private function initializeHandler(event:Event):void { var loader:URLLoader = new URLLoader( ); // In order to test this you'll need to specify a URL of a file that // exists outside of the security sandbox. loader.load(new URLRequest("data.xml")); loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); } private function securityErrorHandler(event:SecurityErrorEvent):void { errors.text += event + "\n"; } ]]> </mx:Script> <mx:TextArea id="errors" /> </mx:Application>
Using XML
XML is a standard protocol for transferring, storing, and reading data for a variety of purposes, including application initialization parameters, data sets, and remote procedure calls. Flex applications can work with XML by using Flash Player’s native support.
Flash Player 9 supports two mechanisms for working with XML: a legacy XMLDocument
class and the new XML
class that implements the ECMAScript for XML (E4X) standard. All XML examples in this book use E4X unless otherwise noted.
Creating XML Objects
There are two ways to create XML
objects in ActionScript: using XML literals or with the XML
constructor. XML literals are useful when you want to define the XML data directly in the code and you know the exact XML data you want to use. The following example defines an XML literal and assigns it to a variable:
var xml:XML = <books> <book> <title>Programming Flex 2</title> <authors> <author first="Chafic" last="Kazoun" /> <author first="Joey" last="Lott" /> </authors> </book> <book> <title>ActionScript 3.0 Cookbook</title> <authors> <author first="Joey" last="Lott" /> <author first="Keith" last="Peters" /> <author first="Darron" last="Schall" /> </authors> </book> </books>;
Tip
We’ll assume that this is the XML
object referenced by the remainder of the XML examples in this chapter.
If you aren’t able to define the XML data directly in ActionScript, you can load the data as a string and pass it to the XML
constructor. In the following example, loadedXMLData
is a variable containing XML data loaded from an external source at runtime:
var xml:XML = new XML(loadedXMLData);
When you use the XML
constructor, any string data you pass to the constructor is parsed into the XML
object as XML nodes. By default, Flash Player attempts to interpret all string data as XML. That means it interprets whitespace (carriage returns, tabs, etc.) as XML nodes. That can cause unexpected results. Therefore, if the XML string data you pass to an XML
constructor contains extra whitespace (for formatting purposes) that you don’t want interpreted as XML nodes, you should first set the static ignoreWhitespace
property to true
for the XML class, as shown here:
XML.ignoreWhitespace = true; var xml:XML = new XML(loadedXMLData);
Reading XML Data
Once you have an XML object, you can read from the object. There are two basic ways in which you can read the data: by traversing the document object model (DOM) or by accessing the data using E4X syntax. The two techniques are not exclusive of one another: you can use them in conjunction with one another.
Tip
In each case that outputs an XML node, the following examples use the toXMLString( )
method to format the XML node as a string.
When viewing the XML data in light of the DOM, treat it simply as a hierarchical structure of data consisting of parent and child nodes. When looking at the DOM, focus primarily on the structure rather than the content. You can retrieve all the content from an XML object by treating it in this manner, but you access the data by structure by stepping into the XML one node at a time. The XML
class defines a host of methods for retrieving DOM structure information, including the following:
children( )
The
children( )
method returns anXMLList
object with all the child nodes of anXML
object. TheXMLList
class implements a very similar interface to that of XML, and all of the methods discussed in this section apply to bothXML
andXMLList
. AnXMLList
object is essentially an array ofXML
orXMLList
objects. You can even retrieve elements from anXMLList
object using array access notation. For example, the following code retrieves the book nodes as anXMLList
. It then displays the first element from that list:var bookNodes:XMLList = xml.children( ); trace(bookNodes[0].toXMLString( ));
length( )
The
length( )
method returns the number of elements. ForXML
objects, this always returns1
. ForXMLList
objects, it may return more than1
. The following example illustrates thechildren( )
andlength( )
methods used in conjunction. This example displays the titles of each of the books:var bookNodes:XMLList = xml.children( ); for(var i:uint = 0; i < bookNodes.length( ); i++) { trace(bookNodes[i].children()[0].toXMLString( )); }
parent( )
You can retrieve the parent of an
XML
orXMLList
object using theparent( )
method. For example, the following displays the first book node by accessing the title node first, and then it retrieves the parent of that node:trace(xml.children()[0].children()[0].parent().toXMLString( ));
attributes( )
The
attributes( )
method returns anXMLList
object with all the data from the attributes contained within anXML
object. You can call thename( )
method for each attribute in theXMLList
to retrieve the name of the attribute as a string. You can then use that value as a parameter, which you can pass to theattribute( )
method of theXML
object to retrieve the value of the attribute. The following example illustrates how this works:var author0:XML = xml.children()[0].children()[1].children( )[0]; var attributes:XMLList = author0.attributes( ); var attributeName:String; for(var i:uint = 0; i < attributes.length( ); i++) { attributeName = attributes[i].name( ); trace(attributeName + " " + author0.attribute(attributeName)); }
As you can see, traversing the XML DOM is effective but laborious. Often, it’s far more effective to use E4X syntax, particularly when you already know the structure. E4X syntax allows you to access child nodes by name as properties of parent nodes. For example, the following accesses the first book node:
trace(xml.book[0]);
You can chain together this simple E4X syntax as in the following example, which retrieves the first author node of the first book node:
trace(xml.book[0].authors.author[0].toXMLString( ));
E4X also allows you to easily access attributes using the @
symbol. The following uses this syntax to retrieve the value of the first attribute of the author node:
trace(xml.book[0].authors.author[0].@first);
You can also use E4X filters. Filters are enclosed in parentheses within which you specify conditions. The following example retrieves all the author nodes in which the last attribute is Kazoun
:
var authors:XMLList = xml.book.authors.author.(@last == "Kazoun"); for(var i:uint = 0; i < authors.length( ); i++) { trace(authors[i].parent().parent().toXMLString( )); }
Writing to and Editing XML Objects
You can also write to and edit XML objects using ActionScript. There are three things you can do in this category:
Modify existing data.
Add new data.
Remove existing data.
You can modify existing data using the same E4X syntax you use to read the data on the left side of an assignment statement. For example, the following changes the title
of the first book
:
xml.book[0].title = "Programming Flex 2: Edition 1";
The following example changes the name of the second author
of the first
book:
xml.book[0].authors.author[1].@first = "Joseph";
If you want to add new data, you can use the appendChild( )
, prependChild( )
, insertChildBefore( )
, and insertChildAfter( )
methods. Each method inserts a new XML node into an XML
or XMLList
structure. The appendChild( )
and prependChild( )
methods each accept one parameter and insert the node at the end and at the beginning of the structure, respectively. The following adds a new publisher node to each book:
xml.book[0].appendChild(<publisher>O'Reilly</publisher>); xml.book[1].appendChild(<publisher>O'Reilly</publisher>);
You can use the insertChildBefore( )
and insertChildAfter( )
methods to add a new node before or after an existing node. The methods each require two parameters: the new node to add, and a reference to the existing node. The following adds a new publication date node (publicationDate
) between the authors and publisher nodes of the books:
xml.book[0].insertChildAfter(xml.book[0].authors, <publicationDate>2006</ publicationDate>); xml.book[1].insertChildAfter(xml.book[1].authors, <publicationDate>2006</ publicationDate>);
You can remove elements using the delete
operator. The following example first adds a new middle attribute to an author node and then removes it:
xml.book[0].authors.author[1] = <author first="Joey" middle="Persnippity" last="Lott" />; trace(xml.book[0].authors); delete xml.book[0].authors.author[1].@middle; trace(xml.book[0].authors);
Reflection
ActionScript 3.0 supports class reflection using the following functions in the flash.utils
package:
getQualifiedClassName
getQualifiedSuperclassName
getDefinitionByName
describeType
We’ll next discuss each of these functions in more detail.
Getting the Class Name
You can retrieve the name of the class for which an object is an instance using the getQualifiedClassName( )
function. The function requires that you pass it a reference to an object; it then returns the fully qualified class name:
var loader:URLLoader = new URLLoader( ); var className:String = getQualifiedClassName(loader); trace(className); // Displays flash.net.URLLoader
If you want to retrieve the fully qualified superclass name for an object, you can use the getQualifiedSuperclassName( )
function:
var loader:URLLoader = new URLLoader( ); var className:String = getQualifiedSuperclassName(loader); trace(className); // Displays flash.events.EventDispatcher
Getting the Class by Name
If you have a class name, you can retrieve a reference to the class using the getDefinitionByName( )
function. The function requires a string parameter specifying a class name, and it returns an Object
type. The function returns an Object
type rather than a Class
type because it could also theoretically return a reference to a function if you pass it a fully qualified function name (e.g., flash.util.getTimer
). If you’re certain that you’re retrieving a class reference, you can cast the return value to Class
, as in the following example:
var classReference:Class = Class(getDefinitionByName("flash.net.URLLoader"));
Once you’ve retrieved a reference to a class, you can create a new
instance, as follows:
var instance:Object = new classReference( );
Obviously you can use the return value from getQualifiedClassName( )
or getQualifiedSuperclassName( )
in conjunction with getDefinitionByName(
), as in the following example:
var loader:URLLoader = new URLLoader( ); var className:String = getQualifiedClassName(loader); var classReference:Class = Class(getDefinitionByName(className)); var instance:Object = new classReference( );
Class Introspection
You can use describeType( )
to return a description of all the events, public properties, and public methods of an object. Simply pass the method a reference to the object you want to introspect. The method returns an XML
object that details the class name, superclass, various class settings, implemented interfaces, constructor signature, public method signatures, and public properties descriptions.
The following example retrieves the description for a URLLoader
object:
var loader:URLLoader = new URLLoader( ); var description:XML = describeType(loader); trace(description);
The preceding example outputs the following:
<type name="flash.net::URLLoader" base="flash.events::EventDispatcher" isDynamic="false" isFinal="false" isStatic="false"> <metadata name="Event"> <arg key="name" value="httpStatus"/> <arg key="type" value="flash.events.HTTPStatusEvent"/> </metadata> <metadata name="Event"> <arg key="name" value="securityError"/> <arg key="type" value="flash.events.SecurityErrorEvent"/> </metadata> <metadata name="Event"> <arg key="name" value="ioError"/> <arg key="type" value="flash.events.IOErrorEvent"/> </metadata> <metadata name="Event"> <arg key="name" value="progress"/> <arg key="type" value="flash.events.ProgressEvent"/> </metadata> <metadata name="Event"> <arg key="name" value="complete"/> <arg key="type" value="flash.events.Event"/> </metadata> <metadata name="Event"> <arg key="name" value="open"/> <arg key="type" value="flash.events.Event"/> </metadata> <extendsClass type="flash.events::EventDispatcher"/> <extendsClass type="Object"/> <implementsInterface type="flash.events::IEventDispatcher"/> <constructor> <parameter index="1" type="flash.net::URLRequest" optional="true"/> </constructor> <variable name="bytesTotal" type="uint"/> <variable name="data" type="*"/> <method name="load" declaredBy="flash.net::URLLoader" returnType="void"> <parameter index="1" type="flash.net::URLRequest" optional="false"/> </method> <method name="close" declaredBy="flash.net::URLLoader" returnType="void"/> <variable name="dataFormat" type="String"/> <variable name="bytesLoaded" type="uint"/> <method name="dispatchEvent" declaredBy="flash.events::EventDispatcher" returnType="Boolean"> <parameter index="1" type="flash.events::Event" optional="false"/> </method> <method name="toString" declaredBy="flash.events::EventDispatcher" returnType="String"/> <method name="willTrigger" declaredBy="flash.events::EventDispatcher" returnType="Boolean"> <parameter index="1" type="String" optional="false"/> </method> <method name="addEventListener" declaredBy="flash.events::EventDispatcher" returnType="void"> <parameter index="1" type="String" optional="false"/> <parameter index="2" type="Function" optional="false"/> <parameter index="3" type="Boolean" optional="true"/> <parameter index="4" type="int" optional="true"/> <parameter index="5" type="Boolean" optional="true"/> </method> <method name="hasEventListener" declaredBy="flash.events::EventDispatcher" returnType="Boolean"> <parameter index="1" type="String" optional="false"/> </method> <method name="removeEventListener" declaredBy="flash.events::EventDispatcher" returnType="void"> <parameter index="1" type="String" optional="false"/> <parameter index="2" type="Function" optional="false"/> <parameter index="3" type="Boolean" optional="true"/> </method> </type>
With some work, you can create complex systems that use objects to create sophisticated and dynamic applications.
Summary
In this chapter, we discussed the fundamentals of ActionScript 3.0. ActionScript is the ECMAScript-standard-based programming language used by Flex applications. Although the topic of ActionScript is far too complex to discuss comprehensively in one chapter, we have covered many of the basics you’ll need to get started writing ActionScript code, including where to place the code, basic syntax, common data types, how to write classes, the event model, error handling, working with XML, and reflection.
Get Programming Flex 2 now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.