Tutorials, extensions, and source files for ActionScript, Flash, and other Adobe products.

 

Pages: 1 | 2 | 3 | 4 | 5

[WORK IN PROGRESS]

Note: Work in Progress

As a work in progress, expect this content to change over time. Some sections may be added, others removed. What exists now may be changed and reading through it you may find holes or areas of incompletion.

Newest additions, like this paragraph (not counting smaller edits), will have a green line noted in the left margin.

Older but still new edits will have a lighter green color.

There are three levels of edit ages.

Getting Started with ActionScript 3.0 in Adobe Flash CS3

With Flash CS3 comes support for ActionScript 3.0 - the newest, standards-based programming language for Adobe Flash (SWF) movies and applications. More so than in the past, you may find it difficult to get started with ActionScript 3.0 when compared to older versions of ActionScript. The transition to ActionScript 2 from ActionScript 1, for example, can probably be seen as a cakewalk compared to the leap to ActionScript 3.0, especially for someone who is prone to working and coding in the Flash IDE (Integrated Development Environment).

The goal of this article is to help acclimate you to working with ActionScript 3.0. It will focus on using ActionScript 3.0 within the Flash CS3 IDE, the first version of the Flash authoring environment to support this new version of ActionScript.

Requirements

  • Flash CS3
  • A Basic understanding of ActionScript or at least JavaScript

Not using or don't have Flash CS3?  Learn to use ActionScript 3 using the Free Flex 2 SDK with the Beginners Guide to Getting Started with ActionScript 3 (Without Learning Flex).

 

A Brief History of ActionScript in Flash

Flash logo Early syntax of ActionScript 1 with Flash 3 was simple and verbose and functionality was based mainly around frame navigation and basic mouse interaction. This remained consistent until about Flash 5 where ActionScript assumed a form more similar to JavaScript. This provided a great deal more functionality and a "dot-syntax" for variable and method access. ActionScript also became a prototyped language allowing for simple OOP functionality similar to that available in JavaScript. This was enhanced in the following release of Flash, Flash MX (6).

Flash MX 2004 (7) introduced ActionScript 2.0. There were two major improvements that came with ActionScript 2: variable data typing and a new class syntax.  Variable data typing allowed you to specify what kind of value your variables contained, whether it be a number, a string, or any other kind of object or value. This typing association was strictly for compile-time debugging.  What that meant was that any type you associated with a variable would only be used to check for errors when you compiled or published.  If no conflict was found during the compilation process your SWF would be created with all the typing information stripped from it and the ActionScript inside would run without any understanding of the types you assigned to them in your original code.  Though this provided no advantage to the Flash Player during playback, it did provide Flash authors a helpful tool for debugging larger, more complicated applications.

The new class syntax was used to define classes in ActionScript 2 similar to those defined for languages like Java.  Though Flash still didn't really support classes beyond that in the form of prototypes (in the end, ActionScript 2 still basically gets compiled to ActionScript 1), this new syntax provided a familiar style that was helpful for people migrating from other languages and provided a more concrete way to organize class definitions within separate AS files and packages. 

That brings us to Flash CS3 (9; not much in terms of advances in ActionScript happened with Flash 8) with ActionScript 3.0.  Here we have a new ActionScript language that not only received a new version number but also a new virtual machine – the underlying software within the Flash Player that executes ActionScript during playback.

Both ActionScript 1 and ActionScript 2 use AVM1 (ActionScript Virtual Machine 1) as they are essentially the same in terms of needs for playback. Remember, ActionScript 2 mostly only added compile-time type checking and a new syntax which essentially became ActionScript 1 when compiled. ActionScript 3 runs in a completely new virtual machine called AVM2 (or sometimes AVM+) designed specifically, from the ground up. to execute ActionScript 3 and only ActionScript 3 code.  As a result not only can ActionScript 3 movies not directly communicate with ActionScript 1 or ActionScript 2 movies, but you may find that the changes in ActionScript 3 to be much more profound than the jump even from ActionScript 1 to ActionScript 2.

Note: ActionScript 1 and 2

For the remainder of this article, both ActionScript 1 and ActionScript 2 will be referenced together as just ActionScript 2 which is the last version of ActionScript to continue using AVM1.

How different is ActionScript 3?

ActionScript 3 is different.  Very different.  So different, in fact, that it requires a completely new virtual machine to run it.  But at its core, its still ActionScript and as ActionScript you'll notice that many of the commands and programming concepts that applied to ActionScript 1 and ActionScript 2 still pretty much apply to ActionScript 3.  Very little, at least syntactically, has changed.  And sometimes the ActionScript 3 equivalent of ActionScript 2 code will look very similar, if not exactly the same. However, this is not always the case.  And in the end, there are enough changes to make a direct conversion between the two often very difficult.

These changes were necessary, though.  ActionScript 3 was built with efficiency and productivity in mind.  Not just efficiency in development (and this point can be argued for smaller projects but larger projects do benefit), but also playback performance where code in ActionScript 3 can be played back in the Flash Player up to 10 times (if not more) faster than ActionScript 2 code. Yes, you will find that many of the same menial tasks in ActionScript 1 and ActionScript 2 now seem to take twice as long to code in ActionScript 3, but in the end the extra speed and functionality.  The casual coder may look to the sky shaking a fist, cursing, but the advanced programmer will jump with glee in rejoice.

Lets take a look at some of the new features ActionScript 3 brings to the table:

  • Runtime exceptions – errors that are thrown at runtime (during SWF playback) to help debug your project
  • Runtime variable typing – typing which goes beyond compilation and persists during playback
  • Sealed classes – classes based on a static definition for additional robustness and performance
  • Method closures – methods are now bound to their respective class instance so 'this' in methods will never change
  • E4X – a new, easy to work with implementation of XML
  • Regular expressions – native support for regular expressions
  • Namespaces – support for namespaces not only in XML but in class definitions to set custom access to class members
  • int and uint data types – new data types for Number values allowing ActionScript to use faster integer-based math for certain calculations
  • New display list model – a new, flexible approach to managing display objects to be viewed on the screen
  • New event model – a new, listener-based event model with support for event propagation

Flash CS3 IDE

Not only has ActionScript changed, but the Flash CS3 authoring environment also sports an entirely new look.  The new interface sleeker and much more flexible than anything Flash has seen before.


Figure: Flash CS3

Note: Screenshot differences

The panel layout of these screenshots may differ from the default (or your custom) panel layout in Flash CS3.

The first thing you should notice with Flash CS3 is a new start screen - the screen that displays common tasks for having just opened Flash. Under the "Create New" column, you now see 2 options for creating FLA files, one for ActionScript 2.0 and one for ActionScript 3.0. Be sure to select the correct one when starting a new file depending on the version of ActionScript you wish to work with. If you already started working on a file and realized you selected the wrong FLA type, it's OK; these settings can always be changed after you start working with the file using File > Publish Settings....

When you start working with Flash and the new interface you'll notice a lot of additions to docking mechanism of the various Flash panels. You can arrange and dock your panels just about anywhere within the Flash window now using drag and drop (those of you having used Flash 5 may reminisce). Additionally, panels can now be collapsed into icons which, when clicked, will open up the panel as a fly out. At any time you can change a group of inconized panels back to their full display using the double arrow within the dock column's titlebar.

The panel enhancements allow for maximum use of space while still retaining easy access to your much needed panels.  For example, you could iconize the Actions panel where ActionScript is written on the right side of the screen and have it open with a single click only when you need to write code.


Figure: ActionScript panel from icon

When you write code in Flash using ActionScript 3, you're only allowed to write code on the timeline. This is a new restriction that was not true with ActionScript 2. With ActionScript 2 you could write code on the timeline as well as selected on objects on the screen such as buttons or movie clips.  Code then would be added within on() or onClipEvent() blocks and related to some kind of event associated with that object like press or enterFrame. All events for such objects in ActionScript 3 would need to be handled strictly within the timeline (or external definitions).


Figure: ActionScript cannot be assigned to selections

As with Flash 8 and Flash MX 2004 before it, Flash allows you to edit not just FLA files, but also external ActionScript (AS) files.  Like before, when editing AS files, a new document window is created that contains the code in an editor very similar to the Actions panel (the Actions panel itself cannot be used to edit external AS files).


Figure: Script file editing within Flash

Each AS document in Flash CS3 has an option in the top left of the interface to be associated with an open FLA document.  When an association is made, you can test the associated FLA when editing the AS document without having to switch over to that FLA.  Be careful, though. Unlike FLA documents, you will need to be sure to save your AS file before testing your movie. Otherwise your changes will not take effect.

When creating AS files for movie clips (class definitions that extend the MovieClip class) you can associate your class with a movie clip symbol in the library just as you did with previous versions of Flash using the linkage properties.  Additional options such as being able to specify a base class now exist for ActionScript 3.


Figure: Linkage properties

New to FLA documents with ActionScript 3 is the additional option of specifying what is known as a document class for the FLA.  This option is available within the property inspector when you have an FLA open with no objects selected.  This is not unlike class association of movie clip symbols with the linkage properties, only here you are specifying a class for the main timeline.


Figure: Property inspector's Document class option

More about working with external scripts and their association with movie clips in the library or the document will be covered later on.

Variables

Variables are words in code that represent or contain different values or data.  When you create a variable in ActionScript 3, you must use the var keyword.

var myVariableName; // var required

The var keyword has been available in ActionScript 1 since Flash 5 but only now, in ActionScript 3 is it required. The only exception is when defining a new variable value in a dynamic object instance (one whose variable definitions are not predefined) using an explicit reference to that object.

aDynamicObject.newVar = value; // only time var not used

In the above example, newVar is a new variable being defined in the aDynamicObject object without the use of var.  In fact, var can never be used with complex references, that is, any reference that requires a dot (.) or bracket access ([]) to reference the variable.

When defining a variable you must only use numbers, letters, dollar signs ($) and underscores (_) and a variable cannot start with a number.  Whereas bits32, _bits32, and $bits32 are valid, 32bits is not valid for a variable name since it starts with a number. These are the same restrictions that applied to ActionScript 2.

You will also have to be sure not to create naming conflicts with your variable names and any internal variable names already defined in the current scope of your script.  For example, when writing code in any timeline, you are writing code that is being defined for a MovieClip instance – the MovieClip instance that is represented by that timeline.  If you try to define a variable with a name that is the same as a predefined MovieClip variable (or function) you will get an error.

// Any timeline script

var name:String = "Joe"; // Error: A conflict exists with inherited definition (name)

Similarly, you should not name variables after top-level objects or functions like Array, XML, or trace or those definitions will no longer be accessible to you.

Note: Case sensitivity

Since Flash Player 7, ActionScript is case sensitive, so the variables Name and name are not the same.  This still applies to ActionScript 3.

The Flash CS3 Actions panel can sometimes be helpful in identifying conflicts since recognized keywords are highlighted as blue. If you are unsure if a variable name you are using is a conflict, check the documentation for MovieClip and see what properties and methods already exist for MovieClip (be sure to include inherited properties and methods)

New to ActionScript 3 is the restriction that you can only declare a variable with var once in any one scope or timeline in code.  In other words, if you declare the variable x at the top of your script and want to use it again at the bottom of your script, you should not use the var keyword for that variable again

var x = value; // ok

… 

var x = differentValue; // error; you can only use var once

When defining variables on the timeline in Flash, this also applies to all frames in the same timeline, not just the current frame. So if you define or declare variable x in frame 1 using var, you cannot use var with that variable again even in a different frame.

When declaring variables with the var keyword (and only with the var [or const] keyword) you have the option of specifying a variable type.  A variable's type describes the kind of value it will be holding.  This was a new feature in ActionScript 2 and continues to exist in ActionScript 3 in the same format.  So, for example, if you wanted the variable x to hold a number value, you would specify it as being of the type Number by using a colon and the term Number directly following the variable name:

var x:Number; // variable x contains number values

In both versions of ActionScript, typing like is optional.  ActionScript 3, however, is different in that it will also retain type information during movie playback, unlike ActionScript 2 which used it strictly for compile-time (during publishing) error checking.  This means that you will have to be much more respective of your type decisions, especially since you cannot redefine a variable with var a second time in ActionScript 3 (doing this in ActionScript 2 would let you use different types for one variable). You will also find that this behavior can be a little troublesome as you start working with type conflicts further down the road.

By not typing a variable at all, you can use any type you want for that variable.  ActionScript 3 also provides a special "untyped" type that represents just that – no type. It is represented by an asterisk (*).

var anyValue:*; // variable can have any type

It's always good to specify some type for your variable as it can lead to better error checking and performance.  By using the untyped type, you can specifically indicate that the variable can have any value without others reading the code to guess.

If you do not supply a variable with a default value, it will be assigned one based on its type.  If no type was supplied, it will be given a value of undefined.  The following list details the default values of different data types in ActionScript 3:

var untyped:*; // (or no typing) undefined

var boolean:Boolean; // false

var number:Number; // NaN

var integer:int; // 0

var unsignedInteger:uint; // 0

var string:String; // null

var object:Object; // null

Any other Object type results in default value of null. It should be noted that values of the type object (any kind of object including arrays and objects created from custom classes) have a default value of null, not undefined.  In fact objects in ActionScript 3 cannot be undefined.  If they have no value, then they are null.  Only with untyped variables or attempting to access variables that do not exist will get a value of undefined.

Number types are now unique in that they can no longer be undefined or null.  If they have no value, they are seen as NaN ("Not a Number").  NaN is a tricky value, however.  You can't really compare NaN with another NaN with the equality operator (==) because they probably won't be the same.  If you ever need to check to see if a number is NaN, you should always use isNaN().

if (isNaN(myNumber))  // checks to see if Number is defined

The int and uint variables types are new in ActionScript 3.  These are special kinds of Numbers that represent 32-bit integers or whole numbers.  The int type is a normal integer and uint is an unsigned integer, or a whole number whose value cannot be negative.  These kinds of numbers can only have whole number values.  They cannot be null, undefined., or even NaN like the Number type on which they are based.  Being that they are based on the Number type, however, you'll notice that they're type identities ("int" and "uint") are not capitalized.  This indicates that there is no specific object type or class definition associated with that type.  Instead, these types essentially share the Number definition with Number types (with the exception of the MIN_VALUE and MAX_VALUE constants which have different values for each type).

Number, int and uint Values
Numeric Type Values
Number 4.9406564584124654e-324 to 1.79769313486231e+308
int -2147483648 to 2147483647 (whole numbers only)
uint 0 to 4294967295 (whole numbers only)

There is one other type that is also not capitalized.  This is the special void type.  This was capitalized in ActionScript 2 but is no longer in ActionScript 3 since, like with int and uint, there is no specific definition associated with it.  This type has not been seen so far as it only applies to functions.

New Basic ActionScritpt 3 Data Types
ActionScript 3.0 ActionScript 2.0
* (not typed)
int Number (loosely)
uint Number (loosely)
void Void

Also new to ActionScript 3 is the behavior of the delete keyword. The delete keyword is used to delete variables from an object. Variables defined with var, however, cannot be deleted in ActionScript 3. Only dynamic variables defined within dynamic objects can be deleted with delete. For other variables, the equivalent of deleting would be to set those variables to have a value of null.

As seen above, not all variables can have null values. Variables defined as int, uint, and Number, can only have numeric values (Number also being able to have a value of NaN) which does not include null - the same applying to Boolean values which can be either true or false. For such cases, there is no equivalent to delete. Variables typed as Number could be set to NaN, but int and uint variables have to be numeric at all times and Booleans just either true or false.

// Create a dynamic object with dynamic property

var obj:Object = new Object();

obj.prop = "value";



// delete dynamic property on obj using delete

delete obj.prop



// cannot delete obj, only able to set to null

obj = null;



// int, unit, Number and Boolean

// types cannot be deleted

var intNum:int = 0;

var uintNum:uint = 0;

var numNum:Number = NaN;

var bool:Boolean = false;

Functions

Functions define reusable chunks of code, or custom operations in ActionScript.  By creating a function you can perform the same operation multiple times without having to write the same code over again for each time you want to use it. Instead, all you do is call the function using its function name.

There are two ways to define functions in ActionScript.  You can create a named function using the form function [functionName] ([parameters]) { [code] } or you can define an anonymous function using var [functionName] = function ([parameters]) { [code] }.  Named functions create function or method definitions while anonymous functions keep variables which reference a "free floating" function definition.

// Named function

function doubleNumber(num) {

	return num*2;

}
// Same function defined as an anonymous function

// defined within the variable doubleNumber

var doubleNumber = function(num) {

	return num*2;

}

The above examples create a function with the name doubleNumber which accepts a single number value and returns that value multiplied by two.  To use the function, you call it using parentheses (()).

var x:Number = 10;

trace(doubleNumber(x)); // traces 20

As with variables, named functions cannot be defined more than once for any one given timeline in ActionScript 3. Anonymous functions can reference multiple functions over time, but cannot be redefined with var as they are essentially variables. ActionScript 2 allowed you to change any function's definition anytime. In ActionScript 3, you can only change an anonymous function's definition.

When assigning type to functions, define typing information for both the parameter list (the comma separated list of values you can supply the function) as well as the return value, or the value that the function supplies after it's executed.  When using an anonymous function definition, the variable the function is being assigned to would also be typed to Function.

// Named function

function doubleNumber(num:Number):Number {

	return num*2;

}
// Same function defined as an anonymous function

var doubleNumber:Function = function(num:Number):Number {

	return num*2;

}

If a function does not return a value, then its return type should be void.  When a function typed as void is executed, or simply fails to return a value with the return statement, its return value becomes undefined.

function returnsNothing():void {

	// do nothing

}

trace(returnsNothing()); // traces undefined

The returnsNothing function above not only returns nothing, but also accepts no values – it has no parameter list.  If you try to pass values into the function when it has no parameter list defined for it in ActionScript 3, you will get an error.

returnsNothing(3); // Error: Incorrect number of arguments

In ActionScript 2, the Void type was used as the parameter list in a function definition to indicate no parameters.  In ActionScript 3, you just leave the list empty. Using Void in the parameter list in ActionScript 3 will actually make Flash think that a variable named Void is defined for the parameter list of that function.

Note: Parameters vs. arguments

The difference between parameters and arguments is that parameters are the value used to define the function.  Arguments are the actual values provided to the function during use.  You can see arguments as being parameter values.

With ActionScript 3, you can also now define default values for your functions. 

// Here, message parameter is optional

function usesDefault(message:String = "hello"):void {

	trace(message);

} 

usesDefault("test"); // traces "test"

usesDefault(); // traces "hello"

By using defaults you not only get to specify values for parameters not used by the function caller, but it also lets you define functions with optional parameters, or parameters that aren't required to be used.  Those parameters that do not have default values must be provided when the function is called in ActionScript 3.  Because of this, all optional parameters must be defined at the end of a parameter list.  You cannot have a required parameter defined after an optional.

// Error: Required parameters are not

// permitted after optional parameters

function usesDefault(message:String = "hello", num:Number):void {

	// code

}
// Correct; usesDefault needs at 

// least 1 argument, accepts 2 at max

function usesDefault(num:Number, message:String = "hello"):void {

	// code

}

What if you wanted to allow a function to be called with any number of arguments?  In ActionScript 2, you could do this simply by omitting any parameter list and referencing the arguments using the arguments object in the function.   In ActionScript 3, having no parameter list means the function cannot be called with any arguments.  Instead, you have to use a new parameter type known as …(rest).  This parameter goes at the end of your parameter list (or it can represent your entire parameter list) and indicates that any number of arguments can be used when calling the function.  The …(rest) parameter is written as …argumentsArrayName where argumentsArrayName is the name of the array that will contain the arguments passed.

// Using the ...(rest) parameter

function passAnything(...statements):void {

	trace(statements.length +": "+ statements);

}

passAnything(); // traces 0:

passAnything(1); // traces 1: 1

passAnything("a", true, 0); // traces 3: a,true,0

Note: Access to caller and callee

When using …(rest) parameter, the arguments object is not available to the function call.  Instead, the …(rest) parameter is to be used to obtain the arguments passed.  Unlike arguments, however, …(rest) does not have the caller property used to reference the current function.  In ActionScript 3, neither arguments nor …(rest) have the callee property used to reference the function calling the current function (callee was available in the arguments object in ActionScript 2 but was removed in ActionScript 3).

Objects, Properties, Methods, and Classes

Objects are complex values that contain, or can contain, additional values or variables known as properties.  The most basic kind of object is an Object object and is created using new Object().

// Creating a new object instance

var myObject:Object = new Object();

There are other kinds of objects in ActionScript that behave similarly.  Every timeline in Flash, for instance, represents the timeline of a movie clip symbol which in ActionScript is represented by a MovieClip object or instance. The name variable of a timeline or MovieClip is a property of that MovieClip instance.

// Main timeline

trace(name); // traces "root1"

Functions defined in objects are known as methods. Together, properties and methods make up an object's members. All of the "publically" availablemembers (those to which you have access to) of an object represent its interface. Methods unique to MovieClip instances include methods like gotoAndPlay() and gotoAndStop().

Primitive values like Boolean (true or false), Number (numeric values), and String (text characters) are not objects in the true sense as they represent basic values and do not act as containers for other values. Flash does, however, associate these primitives with certain object kinds (Boolean, Number, and String), or classes, which grants them certain object-like functionality.  So, for instance, you can extract a certain chunk of text from a String primitive using the String.slice() method of the String class.

Classes are what define objects.  They also act as an object type.  The Array class, for instance, defines what properties and methods exist in Array instances (whose type is Array). When you look through the documentation available for Arrays, you're looking at a reference to the Array class. 

var arrayInstance:Array = new Array(); // instance of Array class

Since ActionScript 2, some classes in ActionScript were specified as being sealed (not dynamic). When a class is sealed, it means that instances of that class cannot have any additional variables or properties defined for them outside of those specified in the class's definition.  The Object and Array classes in ActionScript are dynamic.  You can define what ever variable values you want those objects.  The Sound class, on the other hand, is an example of a sealed class since you cannot dynamically create any variable value you want within a Sound instance.

// ActionScript 2 and 3

var array:Array = new Array();

array.customValue = 1; // OK



var sound:Sound = new Sound();

sound.customValue = 2; // Error: Access of possibly undefined property

In ActionScript 2, enforcement of dynamic or sealed classes was handled by the compiler.  Because of this, you could work around the restriction of sealed classes using the array access operator to reference variables

// ActionScript 2 workaround

var sound:Sound = new Sound();

sound["customValue"] = 2; // Works

This is no longer the case in ActionScript 3.  Sealed classes in ActionScript 3 are enforced not only at compile time, but also runtime. This, however, is necessary to ActionScript 3 since it uses the nature of sealed classes to improve performance.

As you work with different objects in ActionScript, you will need to note which objects are dynamic and which are not.  Here is a list of commonly used dynamic classes:

  • Object
  • Array
  • Date
  • Dictionary*
  • Error (and most other Error Classes)
  • MovieClip
  • RegExp*
  • StyleSheet
  • URLVariables*
  • XML* (and XMLList*)

* New to ActionScript 3

The Dictionary Class

The Dictionary class represents a new kind of Object in ActionScript 3.  Dictionary objects have the special ability of being able to use object references as its keys, or variable names. Normal Object instances (and other instances of dynamic classes) use normal variable names which essentially equates to strings (Arrays also use numbers though they can equate to strings in terms of how they are treated as keys). Dictionaries can use actual objects references.

// Only Dictionary instances can have

// object references as keys

var arr:Array = new Array();

arr[0] = "value";



var obj:Object = new Object();

obj["variable"] = "value";



var dict:Dictionary = new Dictionary();

dict[arr] = "value1";

dict[obj] = "value2";

If you attempt to use objects as keys within normal, generic Object instances, the keys used will actually become the string representation of those objects, not the actual objects themselves as is the case with the Dictionary class.

Dictionaries are most often used to keep information about other objects when those other objects aren't capable of facilitating that information themselves. For example, if you have a collection of Point instances (where Point is a sealed class meaning additional values cannot be assigned to instances of that class) and you need to have a name value to be associated with each one of those points, what you can do is use a Dictionary instance to contain the names of each Point using the Point instance as a key.

// Use Dictionary for name association with inatances

// Assuming ptA - ptC are Point instances

var names:Dictionary = new Dictionary();

names[ptA] = "A";

names[ptB] = "B";

names[ptC] = "C";



// Point A properties

ptA.x; // x value

ptA.y; // y value

names[ptA]; // name ("A")

Because Point instances have no name property, and because they are not dynamic (allowing you to create your own on those instances), the names Dictionary instance here is used to store Point names using the points themselves as a key to their respective name value. This would not be possible with generic Object instances since they can take only variable names as keys (strings or numbers, not instances).

The Value of this

The this keyword in ActionScript is used to access the current scope, or the object the code in the current block is being run in the context of.  Using this on the timeline will reference the MovieClip instance to which that timeline belongs.

// Main timeline

trace(this); // [object MainTimeline]

In functions, referencing this references the object in which the current function is defined.  Since the same function can be easily defined in multiple objects, a single function can make use of the this reference and perform actions on different objects based on which object it is being called from.

// The this reference depends on

// the object "owning" the function call

var joe:Object = new Object();

joe.name = "Joe";

joe.showName = function():void {

	trace(this.name);

}



var jane:Object = new Object();

jane.name = "Jane";

jane.showName = joe.showName;



joe.showName(); // traces "Joe" 

jane.showName(); // traces "Jane"

Here, there was only one function definition for showName (anonymous), initially defined to the showName variable in the joe object.  That function was then assigned to the jane object, again using the variable name showName – one function, two references to it in two different objects.  The object from which the function is being called determines which object the this keyword references.

This behavior was consistent for ActionScript 2 for all functions.  Now, in ActionScript 3, this is only the case for anonymous functions.  Named functions in ActionScript 3 now support method closures, or are bound to the object for which they are initially defined.  If the above example can be written again using a named function.  Watch what happens when the functions are called from their respective objects.

// In ActionScript 3, this in named functions always reference

// the object of the scope in which they were defined

function showName():void {

	trace(this.name);

}



var joe:Object = new Object();

joe.name = "Joe";

joe.showName = showName



var jane:Object = new Object();

jane.name = "Jane";

jane.showName = showName;



joe.showName(); // traces "root1" 

jane.showName(); // traces "root1" 

It doesn't matter what object the showName function is defined, it's reference to this will always be the main timeline (root1).  This is because, as a named function, with method closure in ActionScript 3, this will always reference the object instance of the original context of the function definition.  This is especially useful for event handling where, in the past, workarounds had to be used to maintain a valid reference to the instance for which a handler as defined (i.e. using Delegate (mx.utils.Delegate) in ActionScript 2).

Iteration

Iteration is the process of cycling through the various properties defined within a system or object. In ActionScript 2, inherently all explicit definitions within an object could be iterated through using for..in. The only way to prevent iteration for any or all of those properties was to use an undocumented method called ASSetPropFlags(). In ActionScript 3 iteration with for..in only applies to dynamic definitions in dynamic objects.  That means class-defined methods or properties will not be seen through iteration within any object, nor is there a way to make them be seen. You can hide dynamic definitions from iteration using the ActionScript 3 setPropertyIsEnumerable() function.

The Array class is a dynamic class that has non-dynamic definitions. Using for..in, you can access only the dynamic definitions within that class, even though the other defnitions still exist within that class.

// Create a list array

var list:Array = new Array();

list[0] = "bread";

list[1] = "milk";

list.type = "grocery";



// Iterate through properties in list

var prop:String;

for (prop in list) {

	trace(prop + ": " + list[prop]);

}

/* output

0: bread

1: milk

type: grocery

*/



// length is an Array property but not

// enumerable since part of class definition

trace(list.length); // traces 2



// Hide type property from enumeration

list.setPropertyIsEnumerable("type", false);



// length can not be made enumerable

// through setPropertyIsEnumerable

list.setPropertyIsEnumerable("length", true);

for (prop in list) {

	trace(prop + ": " + list[prop]);

}

/* output

0: bread

1: milk

*/

Notice that length cannot be found in enumeration even if attempted to be set visible through setPropertyIsEnumerable. This is because it is part of that class definition. In fact, any variable declared with var is assumed to be part of a class definition. This means that even variables defined within the timeline will not be enumerable for that timeline.

// var-declared variables do not enumerate

var a:Number = 1;

var b:Number = 2;



for (var prop:String in this){

	trace(prop + ": " + this[prop]);

}

// traces no output

To make timeline variables enumerable, you have to define them as dynamic properties. To do that, you have to define the variable using this. Dynamic variables defined in this manner, however, cannot be typed.

// dynamic variables enumerate

this.a = 1;

this.b = 2;



for (var prop:String in this){

	trace(prop + ": " + this[prop]);

}

/* output

b: 2

a: 1

*/

 

for each

Statements used for iteration in ActionScript 2 include while, do..while, for, and for..in. ActionScript 3 still supports all of these but also adds another new statement, for each..in.

The for each..in statement is like a simplified for..in.  Unlike for..in, for each..in iterates through object values, not object variable names or keys.  If you don't need to know the keys for the object values during iteration, you'll probably want to use a for each..in instead of a for..in.

// for..each iterates through values (not keys)

var obj:Object = new Object();

obj.a = 1;

obj.b = 2;

obj.c = 3;



for (var key:String in obj) {

	trace(key); // key (a, b, c)

	trace(obj[key]); // value (1, 2, 3)

}

for each (var value:* in obj) {

	trace(value); // value without key (1, 2, 3)

}

The first for..in loop will trace both the keys (a, b, and c) as well as the values (1, 2, and 3) while the for each will only trace the values (1, 2, 3) and will have no way of accessing which keys are used to define those vaules.

Continue reading »

Pages: 1 | 2 | 3 | 4 | 5