Initializing Array inside class in AS2

This is a bug in AS2, as I found out. Read the follow-up below.

In most situations (although I haven’t figure out in which situations), as a member of a class, instance variables that are type of array needs to be declared either in the constructor or in other methods of the class, instead of being constructed in the instance variable declaration.

So instead of doing:

class SlideTray extends UIComponent{

__inSlidesArray:Array = new Array();

}

We need to say:

class SlideTray extends UIComponent{

var __inSlidesArray:Array;

function SlideTray(){

__inSlidesArray = new Array();

}

}

This way, whenever a new instance of SlideTray is created, a fresh empty, new __inSlidesArray array is created. Otherwise, if an array instance is instantiated using instance “var __inSlidesArray :Array=new Array();” statement and if a second instance of SlideTray is created after the first one, its __inSlidesArray will “inherit” the value of the first one!

It’s a surprising discovery that took me about 2 hours to figure out.

My experiment is as follows:

//test class

class TestArray{

//purposefully declare the array before the constructor

var __TA:Array = new Array();

var __NUM:Numer = 7;

function TestArray(){

trace(“number is “+__NUM.toString());

}

public function addItem(o:Object):Void{

__TA.push(o);

}

public function addNum(v:Number):Void{

__NUM += v;

}

public function toString():String{

var arr:String = “array: ” +__TA.toString();

var num:String = “number: “+__NUM.toString();

var info:String = arr+” || “+num;

}

}

//main app

var testArray:TestArray = new TestArray();

testArray.addItem(“haha”);

testArray.addItem(233);

testArray.addNum(12);

//output: ‘array: haha,233 || number: 12’;

trace(“testArray: “+testArray.toString());

var testArray2:TestArray = new TestArray();

//output: ‘array: haha, 233 || number: 7’;

trace(testArray2.toString());

The point is that the array in the newly created object, if created the way as described above, will remain as the same value as that of the last created instance. Debugging work like this will generally take 0.5 – 2 – 4 hours.

So the right way is  to create arrays inside methods/class constructors instead of in instance variable statements.

FOLLOW-UP:

Today for some reason I revisited the post and ran some tests on FB3/AS3, and it turned out it all looked normal in ActionScript 3. For a non-static (non-primitive or primitive) variable (I tested on a data type of Array and Person(name:String, sex:String, age:Number), you can initialize it either in constructor or when you declare the variable. The instance of the class should retain a unique reference to the variable. Of course this is another story for a static variable, which always has one copy in the memory. For the basics of stuff, read "Member Initialization" (p191) on Chapter 4: Initialization & Cleanup of Thinking in Java  3rd Ed by Bruce Eckel.

In AS3, the only difference between initializing a variable inside a method vs. initializing it when you define the variable within a class, is the order of initialization. The compiler initializes variables first before any metod calls - even before the constructor, in the order they are defiend in the class. So if you choose to initialize a variable inside the constructor, it will be initialized twice: once set to its default value when it's defined, and reinitialized within the method.

In AS2, it seems you can only initialize primitives and Arrays; if you try to initialize a class when you define the class variable, you would get an error saying "A class's instance variables may only be initialized to compile-time constant expressions." The comiler will fail at the point of the variable definition. The bug comes when you try to initialize an Array as class variable definition. Flash does it as if you were doing a static var, even if what you are trying to declare is a non-static one, as described above in this post.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: