20 February 2006
Beginning
ActionScript coding conventions are very important for Macromedia Flash designers and developers to ensure that code and applications are structured in a way that is intuitive and beneficial to themselves as well as other people working on the same project. This is particularly important with long code files. When you follow coding conventions, everyone on the design and development team can understand the code and can work more efficiently. This document helps formalize the ActionScript coding process.
The following guidelines encourage consistency for people learning how to write ActionScript code. Adopt best practices at all times, whether you are a designer or developer, or working alone or as part of a team:
Typically, you spend 80% of your development time debugging, troubleshooting, and practicing general maintenance, especially on larger projects. Even when you work on small projects, you'll spend a significant amount of time analyzing and fixing code. The readability of your code is important for your benefit and the benefit of your team members. When you follow naming conventions, you increase readability, which increases workflow and enables you to find and fix any errors in your code. All programmers follow a standardized way of writing code; this improves the project in many ways.
Using naming conventions for your variable names can serve the following important functions:
The following sections contain naming guidelines for writing ActionScript code, such as naming files, variables, constants, components, and so on. The section "Formatting ActionScript Syntax" discusses formatting conventions that are specific to ActionScript, and common in other programming languages. The section "ActionScript Coding Conventions" discusses coding conventions that are specific to writing ActionScript and developing with Flash 8.
Note: Flash Player 7 and 8 loosely follow the ECMAScript (ECMA-262) edition 3 language specification. It is useful to see this specification for information on how the language works.
This section reviews naming guidelines for writing ActionScript code. Naming conventions are important for writing logical code. The primary purpose is to improve the readability of your ActionScript 2.0 code. Remember that all variables must have unique names. Names are case-sensitive in Flash Player 7 and later. Do not use the same name with a different case, because this can be confusing to programmers reading your code and can cause problems in earlier versions of Flash that do not force case sensitivity. Keep the following guidelines in mind when you name items such as variables, files, and classes in Flash:
myPelican rather than mypelican.addUser. Don't use nondescriptive names for methods or variables. For example, if you retrieve a piece of data that is the visitor's user name, you might use the getUserName() method instead of the less descriptive getData() method. This example expresses what is happening rather than how you accomplish it.The following sections offer more detail on naming items such as variables, classes, packages, and constants in your code.
When naming instances and variables, avoid using reserved words, which can cause errors in your code. Reserved words include keywords in the ActionScript language.
Also, do not use any word in the ActionScript 2.0 languages (called a language construct) as an instance or variable name. ActionScript constructs include class names, component class names, method and property names, and interface names.
Warning: Never use different cases to avoid conflicting with reserved words. For example, naming an instance of the textfield TextField class (which doesn't conflict with TextField because Flash is case-sensitive) is a poor coding practice.
Table 1 lists reserved keywords in ActionScript 2.0 that cause errors in your scripts when used as variable names.
add |
and |
Break |
case |
catch |
class |
continue |
default |
delete |
do |
dynamic |
else |
eq |
extends |
false |
finally |
for |
function |
ge |
get |
gt |
if |
ifFrameLoaded |
implements |
import |
in |
instanceof |
interface |
intrinsic |
le |
it |
ne |
new |
not |
null |
on |
onClipEvent |
or |
private |
public |
return |
set |
static |
super |
switch |
tellTarget |
this |
throw |
try |
typeof |
var |
void |
while |
with |
|
|
Table 2 lists words that are reserved for future use in Flash, from the ECMAScript (ECMA-262) edition 4 draft language specification. Avoid using these words because they might be used in future releases of Flash.
as |
abstract |
Boolean |
bytes |
char |
const |
debugger |
double |
enum |
export |
final |
float |
goto |
is |
long |
namespace |
native |
package |
protected |
short |
synchronized |
throws |
transient |
use |
volatile |
Variable names can only contain letters, numbers, and dollar signs ($). Do not begin variable names with numbers. Variables must be unique and they are case-sensitive in Flash Player 7 and later. For example, avoid the following variable names:
my/warthog = true; // includes a slash
my warthogs = true; // includes a space
my.warthogs = true; // includes a dot
5warthogs = 55; // begins with a number
Use strict data typing with your variables whenever possible because it helps you in the following ways:
To add a data type to your variables, you must define the variable using the var keyword. In the following example, when creating a LoadVars object, you would use strict data typing:
var paramsLv:LoadVars = new LoadVars();
Strict data typing provides you with code completion, and ensures that the value of paramsLv contains a LoadVars object. It also ensures that the LoadVars object will not be used to store numeric or string data. Because strict typing relies on the var keyword, you cannot add strict data typing to global variables or properties within an object or array. For more information on strict typing variables, see About Assigning Data Types and Strict Data Typing in Flash Help or the Flash 8 LiveDocs (Learning ActionScript 2.0 in Flash > Data and Data Types > About Data Types > About Assigning Data Types and Strict Data Typing).
Note: Strict data typing does not slow down a SWF file. Type checking occurs at compile time (when the SWF file is created), not at runtime.
Use the following guidelines when you name variables in your code:
firstname and firstName as different variables in your application. Although names are case-sensitive in Flash Player 7 and later, using the same variable name with a different case can be confusing to programmers reading your code and can cause problems in earlier versions of Flash that do not force case sensitivity.textfield = "myTextField";
switch = true;
new = "funk";
For information on adding type annotations, see About Assigning Data Types and Strict Data Typing in Flash Help or the Flash 8 LiveDocs (Learning ActionScript 2.0 in Flash > Data and Data Types > About Data Types > About Assigning Data Types and Strict Data Typing).
i, j, k, m, and n). Use these single-character variable names only for short loop indexes, or when performance optimization and speed are critical. The following example shows this usage:var fontArr:Array = TextField.getFontList();
fontArr.sort();
var i:Number;
for (i = 0; i<fontArr.length; i++) {
trace(fontArr[i]);
}
myFont instead of myfont.newHtmlParser instead of newHTMLParser.var minScoreNum:Number = 10; // minimum score
var maxScoreNum:Number = 500; // maximum score
You can use constants for situations in which you need to refer to a property whose value never changes. This helps you find typographical mistakes in your code that you might not find if you used literals. It also lets you change the value in a single place.
Variables should be lowercase or mixed-case letters; however, use the following guidelines for naming static constants (variables that do not change):
var BASE_URL:String = "http://www.adobe.com"; // constant
var MAX_WIDTH:Number = 10; // constant
Do not directly code numerical constants unless the constant is 1, 0, or –1, which you might use in a for loop as a counter value.
Start Boolean variables with the word "is" (because a Boolean value either "is" or "is not" because of its nature). Therefore, you might use the following for whether a baby is a girl or not (which is a Boolean value):
isGirl
Or for a variable indicating whether a user is logged in (or not), you might use the following:
isLoggedIn
Use the following guidelines when you name functions and methods in your code. For information on writing functions and methods, see Functions and Methods in Flash Help or the Flash 8 LiveDocs (Learning ActionScript 2.0 in Flash > Functions and Methods).
singLoud().getCurrentSong().sing();
boogie();
singLoud();
danceFast();
When you create a new class file, use the following guidelines when you name the class and ActionScript file. For proper formatting, see the following examples of class names:
class Widget;
class PlasticWidget;
class StreamingVideo;
You might have public and private member variables in a class. The class can contain variables that you do not want users to set or access directly. Make these variables private and allow users to access the values only by using getter/setter methods.
The following guidelines apply to naming classes:
NewMember.NewMember or OldMember.NewHtmlParser instead of NewHTMLParser for improved readability.NewMember or OldMember.Witches or BaldPirates). In most cases, it is better to leave the words as qualified nouns instead. A qualifier describes the noun or phrase. For example, instead of "cat" or "buckaneer," you might qualify the noun by using BlackCat or OldBuckaneer.Cat.catWhiskers. Instead, Cat.whiskers is much better.Running, or Gardening. Using these nouns might lead to confusion with methods, states, or other application activities.For more information on interfaces, see Interfaces in Flash Help or the Flash 8 LiveDocs (Learning ActionScript 2.0 in Flash > Interfaces).
It's common for package names to use "reverse domain" naming convention. Examples of reverse domain names include com.adobe for adobe.com, and org.yourdomain for yourdomain.org.
com, mx, or org.com.adobe.projectName to maintain consistency. Another example would be com.adobe.docs.learnAS2.Users for the Learning ActionScript 2.0 book in Flash Help.Pentagons, which is responsible for using the Flash drawing API to draw various kinds of pentagons in documentation examples; its name would be com.adobe.docs.as2.PentagonspackageName is an example of a compound, concatenated package name. Remember to use all lowercase letters for the prefix (com, org, and so on).Starting interface names with an uppercase "I" helps you distinguish an interface from a class. The following interface name, IEmployeeRecords, uses an initial uppercase letter and concatenated words with mixed case, as follows:
interface IEmployeeRecords{}
The following conventions also apply:
Printable is a good example.For more information on interfaces, see Interfaces in Flash Help or the Flash 8 LiveDocs (Learning ActionScript 2.0 in Flash > Interfaces).
Component names have an uppercase first letter, and any concatenated words are written in mixed case. For example, the following default user-interface component set uses concatenated words and mixed case:
Components that do not use concatenated words begin with an uppercase letter. If you develop custom components, use a naming convention to prevent naming incompatibilities with Macromedia components. The names of your components must be different from those of the default set that is included with Flash. If you adopt your own consistent naming convention, it helps you prevent naming conflicts.
Remember that the naming conventions in this section are guidelines. It is most important to use a naming scheme that works well for you and to use it consistently.
This section describes how to use comments in your code. Comments document the decisions you make in the code, answering both how and why. For example, you might describe a workaround in comments. Another developer would be able to find the related code easily for updating or fixing. And finally, the issue might be addressed in a future version of Flash or Flash Player, hence the workaround would no longer be necessary.
Using comments consistently in your ActionScript 2.0 code allows you to describe complex areas of code or important interactions that are not otherwise clear. Comments must clearly explain the intent of the code and not just translate the code. If something is not readily obvious in the code, add comments to it.
If you use the Auto Format tool with your code, you will notice that trailing comments move to the next line. You can add these comments after you format your code, or you must modify the comment's new placement after you use the Auto Format tool.
For information on trailing comments, see Trailing Comments in Flash Help or the Flash 8 LiveDocs (Learning ActionScript 2.0 in Flash > Syntax and Language Fundamentals > About Language Punctuators > About Comments > Trailing Comments).
For information on using comments in classes, see the next section, "Adding Comments to Classes."
Use the following guidelines when you add comments to your code:
/* and */) for multiline comments and single-line comments (//) for short comments. You can also use a trailing comment on the same line as the ActionScript code if necessary.=) or asterisks (*). Instead, use white space to separate your comments from ActionScript code.Note: If you use the Auto Format tool to format ActionScript, you remove the white space. Remember to add it back or use single-line comments (//) to maintain spacing; these lines are easy to remove after you format your code.
Note: Using comments is most important in ActionScript code that is intended to teach an audience. For example, add comments to your code if you are creating sample applications for the purpose of teaching Flash, or if you are writing tutorials about ActionScript code.
The two kinds of comments in a typical class or interface file are documentation comments and implementation comments.
Note: Documentation and implementation comments are not formally represented in the ActionScript language. However, they are commonly used by developers when writing class and interface files.
You use documentation comments to describe the code's specifications, but not the implementation. You use implementation comments to comment out code or to comment on the implementation of particular sections of code. Documentation comments are delimited with /** and */, and implementation comments are delimited with /* and */.
Use documentation comments to describe interfaces, classes, methods, and constructors. Include one documentation comment per class, interface, or member, and place it directly before the declaration. If you have additional information to document that does not fit into the documentation comments, use implementation comments (in the format of block comments or single-line comments).
Start classes with a standard comment, which uses the following format:
/**
User class
version 1.2
3/21/2006
Copyright Adobe Systems, Inc.
*/
After the documentation comments, declare the class. Implementation comments should directly follow the declaration.
Note: Don't include comments that do not directly relate to the class that's being read. For example, don't include comments that describe the corresponding package.
Use block, single-line, and trailing comments within the body of your class to comment on your ActionScript code.
One of the most important aspects about programming is consistency, whether it relates to variable naming schemes (covered in the earlier section, "Naming Conventions"), formatting code (covered in the later section, "Formatting ActionScript Syntax"), or coding standards and the placement of your ActionScript 2.0 code, which is covered in this section. You dramatically simplify code debugging and maintenance if your code is organized and adheres to standards.
Whenever possible, put your ActionScript 2.0 code in a single location, such as in one or more external ActionScript files or on Frame 1 of the Timeline (when placed on the timeline, the code is called a frame script).
If you put your ActionScript code in a frame script, put the ActionScript code on the first or second frame on the Timeline, in a layer called Actions, which is the first or second layer on the Timeline. Sometimes you might create two layers—an acceptable practice—for ActionScript to separate functions. Some Flash applications do not always put all your code in a single place (in particular, when you use screens or behaviors).
Despite these rare exceptions, you can usually put all your code in the same location. The following are the advantages of placing your ActionScript in a single location:
One of the most difficult parts of debugging a FLA file is finding all the code. After you find all the code, you must figure out how it interacts with other pieces of code along with the FLA file. If you put all your code in a single frame, it is much easier to debug because it is centralized, and these problems occur less frequently. For information on attaching code to objects (and decentralizing your code), see the next section, "Attaching Code to Objects." For more information on behaviors and decentralized code, see the section "Behaviors Conventions" in Flash 8 Best Practices.
You must avoid attaching ActionScript code to objects (such as button or movie clip instances) in a FLA file, even in simple or prototype applications. Attaching code to an object means that you select a movie clip, component, or button instance, open the ActionScript editor (the Actions panel or Script window), and add ActionScript code by using the on() or onClipEvent() handler functions.
This practice is strongly discouraged for the following reasons:
Some Flash users might say it is easier to learn ActionScript by attaching code to an object. Some also say it might be easier to add simple code, or write about or teach ActionScript this way. However, the contrast between two styles of coding (code placed on objects, and frame scripts) can be confusing to developers who are learning ActionScript and should be avoided. Also, users who learn how to write code attached to objects often have to relearn how to place the equivalent code as a frame script at a later date. This is why consistency throughout the learning process, by learning how to write frame scripts, has advantages.
Attaching ActionScript code to a button called myBtn appears as follows. Avoid this method:
on (release) {
// Do something.
}
Note: However, placing the equivalent ActionScript code on a timeline appears as follows:
// good code
myBtn.onRelease = function() {
// Do something.
};
For more information, see Syntax and Language Fundamentals in Flash Help or the Flash 8 LiveDocs (Learning ActionScript 2.0 in Flash > Syntax and Language Fundamentals).
Note: Using behaviors and screens sometimes involves attaching code to objects, so different practices apply when you use these features. For more information on behaviors and decentralized code, see the section "Behaviors Conventions" in Flash 8 Best Practices. For more information on screens, see the section "Screens Conventions."
Scope is the area where the variable is known and can be used in a SWF file, such as on a timeline, globally across an application, or locally within a function. Typically, you can reference scope in more than one way when you write code. Using scope correctly means that you can create portable and reusable ActionScript code, and you don't risk breaking your applications as you build new modules.
It is important to understand the difference between the global and root scopes. The root scope is unique for each loaded SWF file. The global scope applies to all timelines and scopes within SWF files. You use relative addressing rather than references to root timelines, because relative addressing makes your code reusable and portable.
You can use several methods to target instances that let you avoid using _root; these methods are discussed later in this section. Avoid using _root in ActionScript 2.0 because SWF files that load into other SWF files might not work correctly. The _root identifier targets the base SWF file that is loading, not the SWF file using relative addressing instead of _root. This issue limits code portability in SWF files that are loaded into another file, and, particularly, in components and movie clips. You can help resolve problems by using _lockroot, but only use _lockroot when necessary (such as when you are loading a SWF file but do not have access to the FLA file). For more information on using _lockroot, see the next section, "Using _lockroot."
Use this, this._parent, or _parent keywords rather than _root, depending on where your ActionScript 2.0 code is located. The following example shows relative addressing:
myClip.onRelease = function() {
trace(this._parent.myButton._x);
};
All variables must be scoped, except for variables that are function parameters, and local variables. Scope variables relative to their current path whenever possible, using relative addressing, such as the this property. For more information on using the this property, see This Property in Flash Help or the Flash 8 LiveDocs (ActionScript 2.0 Language Reference > ActionScript Language Elements > Global Properties > This Property).
You can use _lockroot to target content as a way to solve the scoping issues sometimes associated with the inappropriate use of _root. Although this solves many problems with applications, consider _lockroot as a work-around for problems caused by using _root. If you experience problems loading content into a SWF file or a component instance, try applying _lockroot to a movie clip that loads the content. For example, if you have a movie clip called myClip loading content, and it stops working after it is loaded, try using the following code, which is placed on a timeline:
this._lockroot = true;
Whenever possible, use the this keyword as a prefix instead of omitting the keyword, even if your code works without it. Use the this keyword to learn when a method or property belongs to a particular class. For example, for a function on a timeline, you write ActionScript 2.0 code by using the following format:
circleClip.onPress = function() {
this.startDrag();
};
circleClip.onRelease = function() {
this.stopDrag();
};
For a class, use the following format to write code:
class User {
private var username:String;
private var password:String;
function User(username:String, password:String) {
this.username = username;
this.password = password;
}
public function get username():String {
return this.username;
}
public function set username(username:String):Void {
this.username = username;
}
}
If you consistently add the this keyword in these situations, your ActionScript 2.0 code will be much easier to read and understand.
When you port code to ActionScript 2.0 classes, you might have to change how you use the this keyword. For example, if you have a class method that uses a callback function (such as the LoadVars class's onLoad method), it can be difficult to know if the this keyword refers to the class or to the LoadVars object. In this situation, you might need to create a pointer to the current class, as the following example shows:
class Product {
private var m_products_xml:XML;
// Constructor
// targetXmlStr contains the path to an XML file
function Product(targetXmlStr:String) {
/* Create a local reference to the current class.
Even if you are within the XML's onLoad event
handler, you can reference the current class
instead of only the XML packet. */
var thisObj:Product = this;
// Create a local variable, which is used to load the XML file.
var prodXml:XML = new XML();
prodXml.ignoreWhite = true;
prodXml.onLoad = function(success:Boolean) {
if (success) {
/* If the XML successfully loads and parses,
set the class's m_products_xml variable to
the parsed XML document and call the init
function. */
thisObj.m_products_xml = this;
thisObj.init();
} else {
/* There was an error loading the XML file. */
trace("error loading XML");
}
};
// Begin loading the XML document
prodXml.load(targetXmlStr);
}
public function init():Void {
// Display the XML packet
trace(this.m_products_xml);
}
}
Because you are trying to reference the private member variable within an onLoad handler, the this keyword actually refers to the prodXml instance and not to the Product class, which you might expect. For this reason, you must create a pointer to the local class file so that you can directly reference the class from the onLoad handler.
You create classes in separate ActionScript 2.0 files that are imported into a SWF file when it is compiled.
You create classes in separate ActionScript 2.0 files that are imported into a SWF file when you compile an application. To create a class file, you write code that can have a certain methodology and ordering. This methodology is discussed in the following sections.
The following conventions for structuring a class file show how you can order parts of a class to increase the efficiency and improve the readability of your code.
To structure a class file, use the following elements:
UserClass{...}
public function UserClass(username:String, password:String) {...}
Remember the following guidelines when you create a class file:
var prodSkuNum:Number; // Product SKU (identifying) number
var prodQuantityNum:Number; // Quantity of product
This example shows better form than putting both declarations on a single line. Place these declarations at the beginning of a block of code.
var counterNum:Number = 0;
function myMethod() {
for (var counterNum:Number = 0; counterNum<=4; counterNum++) {
// statements;
}
}
This code declares the same variable inside an inner block, which is a practice to avoid.
playBtn.onRelease = playBtn.onRollOut = playsound;
or
class User {
private var m_username:String, m_password:String;
}
For more information, see About Getter and Setter Methods in Flash Help or the Flash 8 LiveDocs (Learning ActionScript 2.0 in Flash > Classes > About working with custom classes in an application > About getter and setter methods).
Use the this keyword as a prefix within your classes for methods and member variables. Although it is not necessary, it makes it easy to tell that a property or method belongs to a class when it has a prefix; without it, you cannot tell if the property or method belongs to the superclass.
You can also use a class name prefix for static variables and methods, even within a class. This helps qualify the references you make. Qualifying references makes for readable code. Depending on what coding environment you are using, your prefixes might also trigger code completion and hinting. The following code demonstrates prefixing a static property with a class name:
class Widget {
public static var widgetCount:Number = 0;
public function Widget() {
Widget.widgetCount++;
}
}
Note: You don't have to add these prefixes, and some developers feel it is unnecessary. Adobe recommends that you add the this keyword as a prefix, because it can improve readability and it helps you write clean code by providing context.
For the initial values for variables, assign a default value or allow the value of undefined, as the following class example shows. When you initialize properties inline, the expression on the right side of an assignment must be a compile-time constant. That is, the expression cannot refer to anything that is set or defined at runtime. Compile-time constants include string literals, numbers, Boolean values, null, and undefined, as well as constructor functions for the following top-level classes: Array, Boolean, Number, Object, and String. This class sets the initial values of m_username and m_password to empty strings:
class User {
private var m_username:String = "";
private var m_password:String = "";
function User(username:String, password:String) {
this.m_username = username;
this.m_password = password;
}
}
Delete variables or make variables null when you no longer need them. Setting variables to null can still enhance performance. This process is commonly called garbage collection. Deleting variables helps optimize memory use during runtime, because unneeded assets are removed from the SWF file. It is better to delete variables than to set them to null. For more information on performance, see the upcoming section, "Optimizing Your Code."
Note: Flash Player 8 has made improvements in garbage collection within Flash Player.
For information on naming variables, see the earlier section, "Naming Variables." For more information on deleting objects, see Delete Statement in Flash Help or the Flash 8 LiveDocs (ActionScript 2.0 Language Reference > ActionScript Language Elements > Statements > Delete Statement).
Note: One of the easiest ways to initialize code by using ActionScript 2.0 is to use classes. You can encapsulate all your initialization for an instance within the class's constructor function, or abstract it into a separate method, which you would explicitly call after the variable is created, as the following code shows:
class Product {
function Product() {
var prodXml:XML = new XML();
prodXml.ignoreWhite = true;
prodXml.onLoad = function(success:Boolean) {
if (success) {
trace("loaded");
} else {
trace("error loading XML");
}
};
prodXml.load("products.xml");
}
}
The following code could be the first function call in the application, and the only one you make for initialization. Frame 1 of a FLA file that is loading XML might use code that is similar to the following ActionScript:
if (init == undefined) {
var prodXml:XML = new XML();
prodXml.ignoreWhite = true;
prodXml.onLoad = function(success:Boolean) {
if (success) {
trace("loaded");
} else {
trace("error loading XML");
}
};
prodXml.load("products.xml");
init = true;
}
Use trace statements in your documents to help you debug your code while authoring the FLA file. For example, by using a trace statement and for loop, you can see the values of variables in the Output panel, such as strings, arrays, and objects, as the following example shows:
var dayArr:Array = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
var numOfDays:Number = dayArr.length;
for (var i = 0; i<numOfDays; i++) {
trace(i+": "+dayArr[i]);
}
This displays the following information in the Output panel:
0: sun
1: mon
2: tue
3: wed
4: thu
5: fri
6: sat
Using a trace statement is an efficient way to debug your ActionScript 2.0. You can remove your trace statements when you publish a SWF file, which makes minor improvements to playback performance. Before you publish a SWF file, open Publish Settings and select Omit Trace Actions on the Flash tab.
For more information on using a trace, see Trace Function in Flash Help or the Flash 8 LiveDocs (ActionScript 2.0 Language Reference > ActionScript Language Elements > Global Functions > Trace Function).
The Debugger tool is also useful for debugging ActionScript code. For more information, see Debugging Applications in Flash Help or the Flash 8 LiveDocs (Learning ActionScript 2.0 in Flash > Debugging Applications).
If you refer to a method in the parent class, prefix the method with super so that other developers know from where the method is invoked. In the following example, you create two classes. You use the super keyword in the Socks class to call functions in the parent class (Clothes). Although both the Socks and Clothes classes have a method called getColor(), using super lets you specifically reference the base class's methods and properties. Create a new AS file called Clothes.as, and enter the following code:
class Clothes {
private var color:String;
function Clothes(paramColor) {
this.color = paramColor;
trace("[Clothes] I am the constructor");
}
function getColor():String {
trace("[Clothes] I am getColor");
return this.color;
}
function setColor(paramColor:String):Void {
this.color = paramColor;
trace("[Clothes] I am setColor");
}
}
Create a new class called Socks that extends the Clothes class, as shown in the following example:
class Socks extends Clothes {
private var color:String;
function Socks(paramColor:String) {
this.color = paramColor;
trace("[Socks] I am the constructor");
}
function getColor():String {
trace("[Socks] I am getColor");
return super.getColor();
}
function setColor(paramColor:String):Void {
this.color = paramColor;
trace("[Socks] I am setColor");
}
}
Then create a new AS or FLA file and enter the following ActionScript in the document:
import Socks;
var mySock:Socks = new Socks("maroon");
trace(" -> "+mySock.getColor());
mySock.setColor("Orange");
trace(" -> "+mySock.getColor());
The following result is displayed in the Output panel:
[Clothes] I am the constructor
[Socks] I am the constructor
[Socks] I am getColor
[Clothes] I am getColor
-> maroon
[Socks] I am setColor
[Socks] I am getColor
[Clothes] I am getColor
-> Orange
If you forgot to put the super keyword in the Socks class's getColor() method, the getColor() method could call itself repeatedly, which would cause the script to fail because of infinite recursion problems. The Output panel would display the following error if you didn't use the super keyword:
[Socks] I am getColor
[Socks] I am getColor
...
[Socks] I am getColor
256 levels of recursion were exceeded in one action list.
This is probably an infinite loop.
Further execution of actions has been disabled in this SWF file.
One of the more confusing concepts to understand for people learning ActionScript 2.0 is using the with statement. Consider the following code that uses the with statement:
this.attachMovie("circleClip", "circle1Clip", 1);
with (circle1Clip) {
_x = 20;
_y = Math.round(Math.random()*20);
_alpha = 15;
createTextField("labelTxt", 100, 0, 20, 100, 22);
labelTxt.text = "Circle 1";
someVariable = true;
}
In this code, you attach a movie clip instance from the library and use the with statement to modify its properties. When you do not specify a variable's scope, you do not always know where you are setting properties, so your code can be confusing. In the previous code, you might expect someVariable to be set within the circle1Clip movie clip, but it is actually set in a timeline of the SWF file.
It is easier to follow what is happening in your code if you explicitly specify the variables scope, instead of relying on the with statement. The following example shows a slightly longer, but better, ActionScript example that specifies the variables scope:
this.attachMovie("circleClip", "circle1Clip", 1);
circle1Clip._x = 20;
circle1Clip._y = Math.round(Math.random()*20);
circle1Clip._alpha = 15;
circle1Clip.createTextField("labelTxt", 100, 0, 20, 100, 22);
circle1Clip.labelTxt.text = "Circle 1";
circle1Clip.someVariable = true;
An exception to this rule is, when you are working with the drawing API to draw shapes, you might have several similar calls to the same methods (such as lineTo or curveTo) because of the drawing API's functionality. For example, when you draw a simple rectangle, you need four separate calls to the lineTo method, as the following code shows:
this.createEmptyMovieClip("rectangleClip", 1);
with (rectangleClip) {
lineStyle(2, 0x000000, 100);
beginFill(0xFF0000, 100);
moveTo(0, 0);
lineTo(300, 0);
lineTo(300, 200);
lineTo(0, 200);
lineTo(0, 0);
endFill();
}
If you wrote each lineTo or curveTo method with a fully qualified instance name, the code would quickly become cluttered and difficult to read and debug.
Reuse blocks of code whenever possible. One way you can reuse code is by calling a function multiple times, instead of creating different code each time. Functions can be generic pieces of code; therefore, you can use the same blocks of code for slightly different purposes in a SWF file. Reusing code lets you create efficient applications and minimize the ActionScript 2.0 code that you must write, which reduces development time. You can create functions on a timeline, in a class file, or write ActionScript that resides in a code-based component, and reuse them in a variety of ways.
If you are using ActionScript 2.0, avoid writing functions on a timeline. When you use ActionScript 2.0, place functions into class files whenever possible, as the following example shows:
class Circle {
public function area(radius:Number):Number {
return (Math.PI*Math.pow(radius, 2));
}
public function perimeter(radius:Number):Number {
return (2 * Math.PI * radius);
}
public function diameter(radius:Number):Number {
return (radius * 2);
}
}
Use the following syntax when you create functions:
function myCircle(radius:Number):Number {
//...
}
Avoid using the following syntax, which is difficult to read:
myCircle = function(radius:Number):Number {
//...
}
The following example puts functions into a class file. This is a best practice when you choose to use ActionScript 2.0, because it maximizes code reusability. To reuse the functions in other applications, import the existing class rather than rewrite the code from scratch, or duplicate the functions in the new application.
class mx.site.Utils {
static function randomRange(min:Number, max:Number):Number {
if (min>max) {
var temp:Number = min;
min = max;
max = temp;
}
return (Math.floor(Math.random()*(max-min+1))+min);
}
static function arrayMin(numArr:Array):Number {
if (numArr.length == 0) {
return Number.NaN;
}
numArr.sort(Array.NUMERIC | Array.DESCENDING);
var min:Number = Number(numArr.pop());
return min;
}
static function arrayMax(numArr:Array):Number {
if (numArr.length == 0) {
return undefined;
}
numArr.sort(Array.NUMERIC);
var max:Number = Number(numArr.pop());
return max;
}
}
You might use these functions by adding the following ActionScript to your FLA file:
import mx.site.Utils;
var randomMonth:Number = Utils.randomRange(0, 11);
var min:Number = Utils.arrayMin([3, 3, 5, 34, 2, 1, 1, -3]);
var max:Number = Utils.arrayMax([3, 3, 5, 34, 2, 1, 1, -3]);
trace("month: "+randomMonth);
trace("min: "+min);
trace("max: "+max);
The onEnterFrame event handler is useful because Flash can use it to repeat code at the frame rate of a SWF file. However, limit the amount of repetition that you use in a Flash file as much as possible so that you do not affect performance. For example, if you have a piece of code that repeats whenever the playhead enters a frame, it is processor intensive. This behavior can cause performance problems on computers that play the SWF file. If you use the onEnterFrame event handler for any kind of animation or repetition in your SWF files, delete the onEnterFrame handler when you finish using it. In the following ActionScript 2.0 code, you stop repetition by deleting the onEnterFrame event handler:
circleClip.onEnterFrame = function() {
circleClip._alpha -= 5;
if (circleClip._alpha<=0) {
circleClip.unloadMovie();
delete this.onEnterFrame;
trace("deleted onEnterFrame");
}
};
Similarly, limit the use of setInterval, and remember to clear the interval when you finish using it to reduce processor requirements for the SWF file.
If you compile a SWF file that contains ActionScript 2.0 with publish settings set to Flash Player 6 and ActionScript 1.0, your code functions as long as it does not use ActionScript 2.0 classes. No case sensitivity is involved with the code, only Flash Player. Therefore, if you compile your SWF file with Publish Settings set to Flash Player 7 or 8 and ActionScript 1.0, Flash enforces case sensitivity.
Data type annotations (strict data types) are enforced at compile time for Flash Player 7 and 8 when you have publish settings set to ActionScript 2.0.
ActionScript 2.0 compiles to ActionScript 1.0 bytecode when you publish your applications, so you can target Flash Player 6, 7, or 8 while working with ActionScript 2.0.
Remember the following guidelines when you optimize your code:
eval() function or array access operator. Often, setting the local reference once is preferable and more efficient.Array.length to a variable before a loop. Assign Array.length to a variable before a loop to use as its condition, rather than using myArr.length itself. For example:var fontArr:Array = TextField.getFontList();
var arrayLen:Number = fontArr.length;
for (var i:Number = 0; i < arrayLen; i++) {
trace(fontArr[i]);
}
instead of:
var fontArr:Array = TextField.getFontList();
for (var i:Number = 0; i < fontArr.length; i++) {
trace(fontArr[i]);
}
setInterval() function).var keyword when declaring a variable.Formatting ActionScript 2.0 code in a standardized way is essential to writing maintainable code, and it's easier for other developers to understand and modify. For example, it would be extremely difficult to follow the logic of a FLA file that has no indenting or comments, as well as inconsistent naming conventions and formatting. By indenting blocks of code (such as loops and if statements), you make the code easy to read and debug.
When you use spaces, line breaks, and tab indents to add white space to your code, you increase your code's readability. White space enhances readability because it helps show the code hierarchy. Making your ActionScript 2.0 easier to understand by making it more readable is important for students as well as for experienced users working on complex projects. Legibility is also important when you are debugging ActionScript code, because it is much easier to spot errors when code is formatted correctly and is properly spaced.
You can format or write a piece of ActionScript 2.0 code several ways. You'll find differences in the way developers choose to format the syntax across multiple lines in the ActionScript editor (the Actions panel or Script window), such as where you put braces ({}) or parentheses (()).
Adobe recommends the following formatting points to help promote readability in your ActionScript code.
{}) properly. Aligned braces improve the readability of your code. If your ActionScript syntax is correct, Flash automatically indents the code correctly when you press Enter (Windows) or Return (Macintosh). You can also click the Auto Format button in the ActionScript editor (the Actions panel or Script window) to indent your ActionScript code if the syntax is correct.()). The following ActionScript code shows an example of this:do {
// something
} while (condition);
function checkLogin():Boolean {
// statements;
}
checkLogin();
or
printSize("size is " + foo + "\n");
function addItems(item1:Number, item2:Number):Number {
return (item1 + item2);
}
var sum:Number = addItems(1, 3);
//good
var sum:Number = 7 + 3;
//bad
var sum:Number=7+3;
An exception to this guideline is the dot (.) operator.
++) and decrement (--), as shown in the following example:while (d++ = s++)
-2, -1, 0
//bad
( "size is " + foo + "\n" );
//good
("size is " + foo + "\n");
theNum++; // Correct
theOtherNum++; // Correct
aNum++; anOtherNum++; // Incorrect
var myNum:Number = (a = b + c) + d;
var a:Number = b + c;
var myNum:Number = a + d;
Note: You can control auto-indentation and indentation settings by selecting Edit > Preferences (Windows) or Flash > Preferences (Macintosh), and then selecting the ActionScript tab.
Use the following guidelines when you write conditional statements:
if, else..if, and if..else statements{}) for if statements// if statement
if (condition) {
// statements
}
// if..else statement
if (condition) {
// statements
} else {
// statements
}
// else..if statement
if (condition) {
// statements
} else if (condition) {
// statements
} else {
// statements
}
When you write complex conditions, it is good form to use parentheses (()) to group conditions. If you don't use parentheses, you (or others working with your ActionScript 2.0 code) might run into operator precedence errors.
For example, the following code does not use parentheses around the conditions:
if (fruit == apple && veggie == leek) {}
The following code uses good form by adding parentheses around conditions:
if ((fruit == apple) && (veggie == leek)) {}
You can write a conditional statement that returns a Boolean value in two ways. The second example is preferable:
if (cartArr.length>0) {
return true;
} else {
return false;
}
Compare this example with the previous one:
// better
return (cartArr.length > 0);
The second snippet is shorter and has fewer expressions to evaluate. It's easier to read and to understand.
The following example checks if the variable y is greater than zero (0), and returns the result of x/y or a value of zero (0).
return ((y > 0) ? x/y : 0);
The following example shows another way to write this code. This example is preferable:
if (y>0) {
return x/y;
} else {
return 0;
}
The shortened if statement syntax from the first example is known as the conditional operator (?:). It lets you convert simple if..else statements into a single line of code. In this case, the shortened syntax reduces readability.
If you must use conditional operators, place the leading condition (before the question mark) inside parentheses to improve the readability of your code. You can see an example of this in the previous code snippet.
Compound statements contain a list of statements within braces ({}). The statements within these braces are indented from the compound statement. The following ActionScript code shows an example of this:
if (a == b) {
// This code is indented.
trace("a == b");
}
Place braces around each statement when it is part of a control structure (if..else or for), even if it contains only a single statement. The following example shows code that is written poorly:
// bad
if (numUsers == 0)
trace("no users found.");
Although this code validates, it is poorly written because it lacks braces around the statements. In this case, if you add another statement after the trace statement, the code executes regardless of whether the numUsers variable equals 0:
// bad
var numUsers:Number = 5;
if (numUsers == 0)
trace("no users found.");
trace("I will execute");
Executing the code despite the numUsers variable can lead to unexpected results. For this reason, add braces, as shown in the following example:
var numUsers:Number = 0;
if (numUsers == 0) {
trace("no users found");
}
When you write a condition, don't add the redundant ==true in your code, as follows:
if (something == true) {
//statements
}
If you are compare against false, you could use if (something==false) or if(!something).
You can write the for statement using the following format:
for (init; condition; update) {
// statements
}
The following structure demonstrates the for statement:
var i:Number;
for (var i = 0; i<4; i++) {
myClip.duplicateMovieClip("newClip" + i + "Clip", i + 10, {_x:i*100, _y:0});
}
Remember to include a space following each expression in a for statement.
You can write while statements using the following format:
while (condition) {
// statements
}
You can write do-while statements using the following format:
do {
// statements
} while (condition);
Don't use parentheses with any return statements that have values. The only time to use parentheses with return statements is when they make the value more obvious, as shown in the third line of the following ActionScript code snippet:
return;
return myCar.paintColor;
// parentheses used to make the return value obvious
return ((paintColor)? paintColor: defaultColor);
Follow these rules when writing switch statements:
switch statements include a default case. The default case is the last case in a switch statement. The default case includes a break statement that prevents a fall-through error if another case is added.case A in the following code example).Your statement should include a comment in the break statement's place, as you can see in the following example after case A. In this example, if the condition matches case A, both cases A and B execute.
You can write switch statements using the following format:
switch (condition) {
case A :
// statements
// falls through
case B :
// statements
break;
case Z :
// statements
break;
default :
// statements
break;
}
Write try..catch and try..catch..finally statements using the following formats:
var myErr:Error;
// try..catch
try {
// statements
} catch (myErr) {
// statements
}
// try..catch..finally
try {
// statements
} catch (myErr) {
// statements
} finally {
// statements
}
You can write listeners for events in several ways in Flash 8. Some popular techniques are shown in the following code examples. The first example shows a properly formatted listener syntax, which uses a Loader component to load content into a SWF file. The progress event starts when content loads, and the complete event indicates when loading finishes.
var boxLdr:mx.controls.Loader;
var ldrListener:Object = new Object();
ldrListener.progress = function(evt:Object) {
trace("loader loading:" + Math.round(evt.target.percentLoaded) + "%");
};
ldrListener.complete = function(evt:Object) {
trace("loader complete:" + evt.target._name);
};
boxLdr.addEventListener("progress", ldrListener);
boxLdr.addEventListener("complete", ldrListener);
boxLdr.load("http://www.helpexamples.com/flash/images/image1.jpg");
A slight variation on the first example in this section is to use the handleEvent method, but this technique is slightly more cumbersome. Adobe does not recommend this technique because you must use a series of if..else statements or a switch statement to detect which event is caught.
var boxLdr:mx.controls.Loader;
var ldrListener:Object = new Object();
ldrListener.handleEvent = function(evt:Object) {
switch (evt.type) {
case "progress" :
trace("loader loading:" + Math.round(evt.target.percentLoaded) + "%");
break;
case "complete" :
trace("loader complete:" + evt.target._name);
break;
}
};
boxLdr.addEventListener("progress", ldrListener);
boxLdr.addEventListener("complete", ldrListener);
boxLdr.load("http://www.helpexamples.com/flash/images/image1.jpg");
Changing your workflow to incorporate best practices (or standardizing your code) can take time and patience. However, you will quickly realize the benefits to your code and workflow. If you're just starting to learn ActionScript, use and refer to this guide frequently to help you form good habits as you learn. If you do this, you can avoid having to retrain yourself later on.
For more information about using ActionScript, please see the following resources:
| 04/23/2012 | Auto-Save and Auto-Recovery |
|---|---|
| 04/23/2012 | Open hyperlinks in new window/tab/pop-up ? |
| 04/21/2012 | PNG transparencies glitched |
| 04/01/2010 | Workaround for JSFL shape selection bug? |
| 02/13/2012 | Randomize an array |
|---|---|
| 02/11/2012 | How to create a Facebook fan page with Flash |
| 02/08/2012 | Digital Clock |
| 01/18/2012 | Recording webcam video & audio in a flv file on local drive |