Introduction to ActionScript 3.0/Variables and Data Type

From Wikibooks, open books for an open world
Jump to: navigation, search
Introduction to ActionScript 3.0
Class structure Variables and Data Type Functions

Key concepts:


  • Data types
  • Primitive data types vs. Composite data types
  • Literals
  • Typecasting
  • The concepts of variables and constants
  • Variable declaration, access and value assignment
  • Statements vs. expressions
  • Rules and conventiosn for variable naming
  • Type checking
  • null
  • Use of * in data typing

Before we start doing any programming work, we need to work on our basics. Let's start with data types and variables.


What is a data type?[edit]

When we work on a Flash project, there are a lot of data and multimedia elements we need to manage: numbers, text, pictures, and so on. A data type is a type of data in our application.

What is a primitive data type?[edit]

A primitive data type is a type of data that isn't based on any other data types. The primitive data types we're going to use are as follows:

  • Number (e.g. 1, -3254, 123.045)
  • uint (e.g. 1, 3254, 123)
  • int (e.g. 1, -3254, 123)
  • String (e.g. "My name is Joe Bloggs", "ActionScript")
  • Boolean (true or false)

The difference between uint and int is that uint is unsigned, meaning it can't be negative. int is signed, so it can be positive. int takes up more space than uint.[1] Number can represent any floating-point number.

ActionScript's data types are much simpler than most computer languages. There is no 'char' type - String is already a primitive data type, and if we want to store a character, we can put it in a string. There's only one kind of string: none of that CHAR/VARCHAR business in SQL.

Note the double quotes around the strings. One should always enclose a string with double quotes. The double quotes tells Flash that it's a string, not a variable name or anything else. true is a Boolean value, while "true" is a string.

The examples above are all examples of literals. Literals are a way of representing certain values, including primitive data types, XML, regular expressions and objects, in textual form. For example, you can't change the value of 3254, can you?

How can I convert between data types?[edit]

DataType(Value) is used to convert between data types. This technique is known as typecasting. For example:

  • To convert a number or Boolean to a string, type String(Value). For example, String(3) yields "3", String(false) yields "false", and String(true) yields "true".
  • To convert a Boolean or string to a number, type Number(Value). For example, Number(true) yields 1, Number(false) yields 0, and Number("12") yields 12.
  • To convert a number into a Boolean, type Boolean(Value). Boolean(0) yields false and Boolean(1) yields true.

When converting a value to Boolean, simple keep this in mind:

  • null, undefined, NaN, 0 and empty strings ("") return false. (We'll discuss null, undefined and NaN in a moment.)
  • Everything else returns true.

Care should be taken when converting between the different types of numbers. For example, uint(-1) gives the number 4294967295. This is because of a peculiarity of the two's complement representation system we won't go into here.

There is more to typecasting than meets the eye, though. As we progress through the book, we will look into this technique with more detail.

What is a composite data type?[edit]

Any data type that is not of a primitive data type is a composite data type. Composite data types are actually classes. The Object class is a prototypical object that has nothing inside it whatsoever. Classes all extend the Object class by default.

What are variables and constants?[edit]

Every entity, of every type, can be stored in a variable. Consider a variable a 'jar'. This jar can be used to store a lot of things. Most jars are of a special shape that only allows it to store one type of variable (which we'll see below). Sometimes, it stores an actual thing; other times, it stores a link to another thing that is too big to put into a jar. A variable's value may change, which is why it is called a variable.

There are many types of variables, including:

  • Instance properties belong to one instant of an object. For example, an apple may have a 'colour' property. Depending on the apple, its value may be "green" or "red".
  • Static properties belong to the class itself, and not the instants. Once it changes, it changes for all instances of that class. For example, the Apple class may have a 'geneSequence' property.
  • Local variables, or variables within a function.
  • Global variables belong to the package rather than the class.

There are equally many types of constant, including:[2]

  • Instance properties belong to one instant of an object. (They are not used very often.)
  • Static properties belong to the class itself, and not the instants. (We will discuss an example of its use later in this chapter.)
  • Local constants, or constants within a function.
  • Global constants belong to the package rather than the class.

This classification will come in handy when we deal with variable and constant access later.

How can I define and assign values to a variable or constant?[edit]

How can I define a variable?[edit]

The syntax for declaring an variable instance property is as follows:

namespaceAttribute var variableName:DataType;

Here's an example:

public var colour:String;

If we want to make it static instead, we simply insert the attribute 'static' after the namespace attribute:

namespaceAttribute static var variableName:DataType;

Another example:

public static var speciesName:String;

Local variables are basically the same story without attributes:

var variableName:DataType;

Obligatory example:

var speciesName:String;


How can I access variables?[edit]

An expression is, in simple words, how we represent a value in code. Examples of expressions include literals (13.4, "hello world", true, etc.), variable names (myVariable), etc. It is contrasted with a statement, which is a command which actually tells the computer to do something.

To do something to a variable, we must access it. That means we need to write an expression whose value is the variable in question. That sounds really abstract, so let's just learn how to access variables!

How can I access instance properties?[edit]

To access an instance property, we write this:

myObjectInstance.myProperty

For example, this expression can access the 'colour' property of an apple:

myAppleInstance.colour

Now, let's say we're inside a function of our Apple class, and we want to write an expression that references the current instance. Simple: We use the 'this' keyword:

this

To access a property of the current instance, we have two choices:

this.myProperty
myProperty

Yes, we don't even have to type in the 'this.' if we don't want to! Well, most of the time. Sometimes, we do need to type in 'this.'. We'll touch on this case in the next chapter - be patient. Meanwhile, here's an example within the Apple class:

 this.colour
 colour


How can I access static properties?[edit]

To access a static property, instead of the name of the instance, you put the class name in front of the dot:

Apple.speciesName

If we're accessing static properties within the same class, we can skip the first part:

speciesName

You cannot have a static property and an instance property with the same name within the same class. Therefore, you don't have to worry about ambiguity just yet.

How can I access local variables?[edit]

To access a local variable, simply type in the name:

colour

However, local variables and static/instance properties can have the same name, resulting in a naming conflict. In this case, we are no longer allowed to be lazy.

var colour:String;
var speciesName:String;
 
colour //This expression refers to the local variable 'colour'.
speciesName //This expression refers to the local variable 'speciesName'.
this.colour //This expression refers to the instance variable 'colour'.
Apple.speciesName //This expresion refers to the instance variable 'speciesName'.

A quick note[edit]

Now let's revisit the example we saw above:

myAppleInstance.colour

Here, myAppleInstance is either a) a local variable or b) a property of the current instance. In the latter case, the above expression 'implies' this expression:

this.myAppleInstance.colour

Apart from using full stops (.) as described above, an alternative way to access a property of a class is to treat the property name as a string:

myObjectInstance["myProperty"]

We'll discuss the uses and demerits of this in a later chapter.

How can I assign a value to a variable?[edit]

So far, we've only declared variables. They do not contain any content. That is not very useful, which is why we should assign a value to the variable.

The syntax for assigning a value to a variable is very simple:

myVariable = myValue;

You should replace myVariable with one of the variable access expressions we described in the above section. For example:

/*This assigns the string "green" to colour.
'colour' can be any of the following:
- The 'colour' property of the current instance,
- The static 'colour' property of the current class,
- or a local variable named 'green'.
In the first and second cases, this line of code should be located INSIDE the apple class.*/
colour = "green"; 
 
/*This assigns the string "green" to the 'colour' property of the current instance.*/
this.colour = "green"; 
 
/*This assigns the string "green" to the 'colour property of the 'myApple' instance.
This line of code should be located OUTSIDE the apple class.
myApple is either a local variable, */
myApple.colour = "green"; 
 
/*This assigns a newly-initialised Juice object to myApple.
This line of code should also be located OUTSIDE the apple class.*/
myApple.juice = new Juice();

What happens when I assign a variable into another variable?[edit]

Now for an important concept! There are actually two separate things that may happen when you assign a variable to another variable. It all depends on whether you're dealing with a primitive data type:

var myString:String = "Hi";
 
/*The computer COPIES the string in myString to "Hi".
myString and myOtherString now refer to two separate data,
located in two separate spots on the computer's memory! */
myOtherString = myString; 
 
myString = "Bye";
/*At this point, we note that:
-The value of myString is "Bye"
-The value of myOtherString is still "hi"
*/
 
var myDog:Dog = new Dog();
myDog.species = "golden retriever";
 
/*The computer passes a REFERENCE to myFirstPet.
myFirstPet and myDog are one entity.
They refer to the same spot on the computer's memory!*/
myFirstPet = myDog; 
 
myDog.species = "peking";
/*At this point, we note that:
-The value of myDog.species is "peking"
-The value of myFirstPet.species is "peking"
as myDog and myFirstPet are now referring to the same entity.
*/
 
/*This line of code assigns a new reference to myDog.
myDog and myFirstPet now refer to two separate entities.*/
myDog = new Dog();
 
myDog.species = "chihuahua";
/*At this point, we note that:
-The value of myDog.species is "chihuahua"
-The value of myFirstPet.species is still "peking"
*/

As the comments above have kindly explained for us, assigning the value of a variable with a primitive data type to another one will copy the datum over. They refer to two different spots in the computer's memory. As you can see above, assigning another variable to myString didn't change myOtherString because they are separate.

On the contrary, assigning the variable containing an object to another variable will only pass a reference to the new variable. They refer to the same spot on the computer's memory. That's why, when we changed the species of myDog, the species of myFirstPet also changed. (A dog can't have two species at the same time, can it?)

However, once we assigned a new instance of Dog into myDog, myDog started referring to a new entity, separate from myFirstPet. Thus changing the species of myDog did not change the species of myFirstPet.

How can I initialise a variable?[edit]

There's a quicker way to declare a variable and assign a value to it. This is called initialising the variable. If we don't initialise a variable, we'll eventually have to do it anyway.

The syntax for initialising a variable is as follows:

attributes var myVariableName:MyDataType" = myInitialValue;

We simple combined the assignment statement and the declaration into one line of code. For variables, this is optional. Recall the variable definition we saw in our Main.as last chapter:

        private var _username:String = "Daniel";

Constants: Basically the same story[edit]

Constants are very similar to variables, except this time, initialisation is compulsory, and you may not assign any values to the constant afterwards. The exact syntax is as follows:

attributes const myConstantName:MyDataType" = myValue;

Looks familiar? It should: we saw one last chapter.

        private const HELLO_WORLD:String = "Hello, world!";

The syntax for accessing constants is exactly the same as that of variables, so we won't repeat everything here. Simply read through the variable access section above, substituting 'variables' for 'constants'.

How should I name my variables and constants?[edit]

What rules restrict my naming?[edit]

Like most programming languages, ActionScript does not allow certain names.

  • All variable names must start with a letter, an underscore (_) or a dollar sign($). Numbers are also allowed after the first character. No other characters should be used.
  • Variable names are case-sensitive. That means thisVariable and thisvariable are two distinct variables.
  • Reserved words are keywords that cannot be used as variable or constant identifiers (or function identifiers, as we'll see next chapter). Here's a list of reserved words (we'll learn the uses of all these keywords in this book):
  • as
  • break
  • case
  • catch
  • class
  • const
  • continue
  • default
  • delete
  • do
  • else
  • extends
  • false
  • finally
  • for
  • function
  • if
  • implements
  • import
  • in
  • instanceof
  • interface
  • internal
  • is
  • native
  • new
  • null
  • package
  • private
  • protected
  • public
  • return
  • super
  • switch
  • this
  • throw
  • try
  • typeof
  • use
  • var
  • void
  • while
  • with
  • Some words can, technically, be used as identifiers, but have special meanings in certain contexts. Such syntactic keywords include:
  • each
  • get
  • set
  • namespace
  • include
  • dynamic
  • final
  • native
  • override
  • static
  • Some words are not reserved words at the moment, but they may be used in future releases of Flash, so it's best not to touch them, either, lest your application should go wrong in future versions of Flash Player. (The 'as' and 'const' keywords, for example, used to belong to this category, and are now on the official list of reserved words. Conversely, the 'intrinsic' keyword was moved from the reserved word list to here.)
  • abstract
  • boolean
  • bytes
  • cast
  • char
  • debugger
  • double
  • enum
  • export
  • float
  • goto
  • intrinsic
  • long
  • prototype
  • short
  • synchronized
  • throws
  • to
  • transient
  • type
  • virtual
  • volatile

What naming conventions should I follow?[edit]

Apart from the rules above, we should also follow naming conventions.

  • Most of the time, variables should always start with a lowercase letter and consist of words smashed together using CamelCase. For example, instead of $Animalspecies, you should name the variable animalSpecies. For private and protected variables, it is common (and sometimes necessary) to add an underscore before the variable name, e.g. _animalSpecies. We'll look at this later.
  • Variable names should be as concise as possible, but should give enough information as to what it is. In general, obscure abbreviations should be avoided.
  • A conventional way to name Boolean variables is to use a verb of the third person at the beginning. The most common type is verb to be + complement, such as isHappy, isPaused, etc. Other examples of good Boolean names include likesCheese, hasPimples, and so on.
  • Constants are named like variables, except everything is in UPPERCASE and SEPARATED_BY_UNDERSCORES.

When is type checking?[edit]

ActionScript 3.0 is a strongly-typed language. That means variables and constants must have a data type stated. When the program is compiled, the compiler will generate an error if you try to 'fit a square peg in a round hole' by putting an object of one type into a variable that accepts another type. For example, look at this code:

var dog:Dog = new Dog();
var cat:Cat = dog;

This code will generate this error:

Implicit coercion of a value with static type Dog to a possibly unrelated type Cat.

Such is the importance of typecasting: it generates an error to help you fix it. Some languages, such as JavaScipt, are weakly-typed languages. Variables can contain data of any type. Therefore, this code does not result in an error (actually, JavaScript doesn't even have a compiler, but that's another story):

var dog = new Dog();
var cat = dog;

As a result, you may spend hours scratching your head wondering why you application isn't working before you realise what happened. Now, putting a dog into a variable for cats may not be the must common error, but once you get to similar classes - such as XML and XMLList - it is common to get confused. In fact, type errors are the second most common type of programming errors, second only to syntax errors.

What is null?[edit]

In ActionScript, there are two values that can fit into all variables: null and undefined. We'll look into null for now, and save undefined for later.

null is a special value that can fit into variables of any type. The only exceptions are Boolean, uint, int and Number, which do not accept null (but accept undefined). When a variable other than these four types is first created, it starts out as a 'null' value. In addition, null is commonly used to indicate that something doesn't exist. For example:

if(myDog == null){ //This lines means 'if the value of myDog is null'
     trace("I don't have a dog!");
}

In the above example, we traced 'I don't have a dog!' if myDog is null. (You don't have to understand the code for now, just the concept.)

This does not work for numbers, however. We'll look into this in a future section.

How can I create a variable without datatyping?[edit]

Occasionally, we want a 'generic' variable that accepts every and any data type. In this case, simply replace the data type with an asterisk (*):

var iHoldAnything:* = new Object;
iHoldAnything = "Hello world!";
iHoldAnything = 12.3;

This technique should be used sparingly to take full advantage of the compiler errors.

How can I determine if an object or datum belongs to a certain type?[edit]

There are two keywords that help us determine the data type of an object: 'typeof' and 'is'.

How can I use typeof?[edit]

The syntax for typeof is as follows:

typeof myExpression

This is an expression that may have several possible values, all self-explanatory strings:

  • "number" - this includes Number, uint and int.
  • "string"
  • "boolean"
  • "function"
  • "object" - everything else.

For example:

var myVariable:uint = 12;
var dataTypeOfMyVariable:String = typeof myVariable;
//The value of dataTypeOfMyVariable is "number".
 
var dataTypeOfDataTypeOfMyVariable:String = typeof dataTypeOfMyVariable ;
//The value of dataTypeOfDataTypeOfMyVariable is "string".

How can I use is?[edit]

'is' is a bit different from typeof. We use 'is' when we already have a data type in mind, and want to see if our expression belongs to that data type. It returns a Boolean variable.

myExpression is MyDataType
var is12AUint:Boolean = 12 is uint; //true
var isNeg12AUint:Boolean = -12 is uint; //false
var isCurrentObjectASprite = this is Sprite;
//true or false, depending on whether the current object is a sprite

Things will get interesting once we get to subclasses. For now, let's be happy with the current uses of 'is'!

Conclusion[edit]

Now that you have an idea how variables, constants and data types work, let's move on to the second chapter: Functions.

Note[edit]

  1. Signed integers need a sign bit in the two's complement representation. This is not required by unsigned integers.
  2. AS3 no longer supports global variables.