Static Initializers in AS3

static illustration
bzzzzzzt

In a nutshell: A static initializer is executed whenever you do anything with that class. It's executed before whatever you wanted to do (e.g. calling the constructor or accessing a field). It's also only executed once.

Many moons ago I released some code which utilized a static initializer. That code worked fine back then, but recent versions of the Flex SDK compiler don't really like it. Well, to tell the truth I also didn't like it, because the construct I used was sorta ugly and, well, pretty wrong.

The hello world of static initializers looks like this:

//static (this comment isn't required, but I recommend using one)
{
    trace('woo! static!');
}

Declaring variables there or using loops doesn't work, however. Loops used to work, but the proper way to handle this is better anyways. All you need is an anonymous function which is invoked directly:

//static
{
    (function():void {
        var i:int;
        for (i = 0; i < 3; i++){
            trace(foo + i);
        }
    }());
}

AS3 has function scope just like JavaScript. This means the declared variables are available within the function they were declared. So, we can use some temporary objects/variables and they will be discarded as soon as we're done with this initialization stuff. They won't waste memory and they also won't clutter up this class' namespace.

A Complete Example

HelloStatic.as

package {
    import flash.display.*;
    public class HelloStatic extends Sprite {
        //static
        {
            trace('hello');
        }
        public function HelloStatic():void {
            trace('world');
            trace(OtherClass.field);
        }
    }
}

OtherClass.as

package {
    public class OtherClass{
        public static var field:String ='not initialized yet';
        //static
        {
            field = 'initialized';
        }
    }
}

Output:

hello
world
initialized

JavaScript Side Story

In JavaScript this sorta odd looking direct invocation of an anonymous function can be written in 3 different ways (AS3 only likes the one I used above, fortunately). The invocation parenthesis can be put outside the wrapping parenthesis. And the wrapping parenthesis can be also omitted. However, the convention I used here makes most sense (it's also recommended by JSLint by the way).

The reason why this one makes most sense is pretty straightforward: There are 2 separate things going on. The first one is the function and its invocation:

function() {
    [...]
}();

And the second one is additional parenthesis which acts as some kind of marker:

(function() {
    [...]
}());

Whenever a function is directly invoked it should be wrapped in parenthesis in order to "announce" this behavior at the very beginning. Starting to read a function's code under the wrong assumption is very irritating indeed. If you use this convention you can avoid that problem completely. Fortunately AS3 forces you to do this.

Comments

Question

I have a little question,what can we do with the Static initializers?
I just can't catch what you want to express?

Questions

It's a little hard to understand .I just wonder what's the difference from the way that we call constructor to initialize variables.And what's the advantage ?Could you give more details on how to use it?Thank you !!

re: Question(s)

A static initializer is useful if there is no constructor and if you still need to initialize something.

A nice example is my DText class. I don't want to calculate the position of each source rectangle for each character over and over again, but I also don't want to use a constructor, since this class' behavior is completely static. Having an instance wouldn't be of much use, because there aren't any properties to keep track of.

You could for example create your own static math class (Math itself is also a static class), which creates look-up tables for all expensive things in a static initializer.

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options