Home Contact

[September 19, 2008]

Dynamic Programming in AS3

Filed under: ActionScript — @ 12:21 am

AS3 provides a built-in data structure that you can use for dynamic programming to supplement your application’s functionality. This structure is the prototype chain.

What’s the prototype chain?

To answer that, let’s start by forgetting about user-defined Classes for the moment, and looking at some older mechanisms that have been common to ActionScript and JavaScript since AS1.

Functions and the new operator

Whenever a Function is created, the Function constructor also creates a new generic Object. The Function gets a property named “prototype” that refers to this new Object. This generic object is a default that you can change by setting the Function’s prototype to a different object, as we shall see.

Now when you the programmer want to create a new custom object, you can do it by invoking a function preceded by the new operator:


var myObject:Object = new SomeFunction();

When used with the new operator, a function is known as a constructor function (not to be confused with a constructor method!), or just a constructor. The new operator modifies the way the function works in three ways:

1. Ordinarily, the keyword this, when used inside a function, is bound to the global object. When a function is invoked with new, a new Object is created, and this refers to that Object. (This is like using the Function.apply() method.)

2. The new Object gets a property named __proto__ that refers to the constructor’s prototype. The Object’s __proto__ is a basis for inheritance — a way to customize the new Object — as described in the next section.

3. If the function returns a non-object value, then when invoked with new, this (the new object) is returned instead. If the function returns an object, that object becomes the value of the new expression, and this is discarded.

You can see that use of the new operator causes the function to behave quite differently. So although there is no formal difference between a constructor function and any other function, the code you put in them will be quite different. Constructor functions are conventionally named with an upper-case first letter as a reminder of the distinction.

Prototype Inheritance

When the runtime encounters a reference to a property of an object, as in myObject.var or myObject.func(), it naturally looks for the property in the object itself. But if it doesn’t find it there, it looks in the object’s __proto__ (the prototype object). Note that the prototype is an object like any other, and when it was created it got a __proto__ reference to a prototype, too. Thus we have a prototype chain. The chain has an end, though, because eventually we reach an Object that was created with new Object(); or with an Object literal in curly braces, and the next object in the chain is the unique and final Object.prototype. The runtime will search the chain until it finds the desired property or until it reaches Object.prototype.

The constructor’s prototype appears as the first element in the new Object’s prototype chain. Thus, although no new Class is created, and the new object’s type is simply Object, this particular prototype has a tangible effect on the object’s behavior that is shared with all other objects that have the same prototype chain. The prototype constitutes the Object’s pseudoclass. (The pseudoclass is often called “class” for simplicity when speaking of AS1 or JavaScript). The instanceof operator works by traversing the prototype chain.

If properties of the prototype are modified, the object naturally inherits the new values. If the object is directly assigned a property of a given name, that property will mask (or “shadow”) a property with the same name on the prototype.

If the constructor function is assigned a different prototype, then objects subsequently created with new SomeFunction() will inherit from the new prototype, but old objects continue to inherit from the original prototype. Normally, if a pseudoclass is to inherit from another, the programmer will explicitly set the constructor’s prototype before creating any objects from it:


function Shape() { this.handle = "shape"; }    // leave default prototype; shape objects will inherit from an Object

function Circle(r) { this.radius = r; }
Circle.prototype = new Shape();    // circle objects will inherit from a shape object

var circle = new Circle();    // circle will have the "handle" property

Note that the constructor function itself, being an object of class Function, inherits properties not from its prototype, but rather from its own __proto__, which is a reference to Function.prototype.

The programmer can also replace an object’s __proto__, changing its pseudoclass at will. This may seem a bit out there, but it was actually the way to set the document type in AS1 and AS2.

All of the above applies equally to JavaScript and to all versions of ActionScript. But ActionScript 3 imposes certain restrictions:
1. Neither package-level functions nor class methods may be used as constructor functions. So a constructor function must be defined outside a package statement, within a method, or in a frame script.

2. The __proto__ property of an object is not accessible to the programmer.

3. In strict mode, passing any parameters to a constructor function that is declared outside a package statement is a compile-time error, even if the function is declared to accept parameters. (This is not the case when the function is defined within the method where it is invoked, or when the function is invoked through a reference defined within the method where it is invoked.) This appears to be a mistake on the part of the compiler.

Bringing it Up to Date

First let’s note that the above stuff is dynamic in that it can all be changed at runtime. Good times. Of course it comes with a price: slower performance, and everything is public and untyped.

Now let’s bring back Classes, and see how they behave compared to these ancestral features of the language.

In AS2, classes were grafted onto the underlying prototype-based language. Class syntax was just that: syntax allowing programmers to ignore the implementation and submit to certain restrictions at compile time. But prototype-based inheritance was all there really was in the VM, and its full power (and dangers) were still available at run time. AS3 is different. It has true classes and class-based inheritance.

When a Class is created, it gets a prototype object just as a Function does. The instances created by new ClassName() inherit from the class prototype, and you can add, delete, or change properties of the class prototype, and those properties are all public and untyped, too. The difference is that you cannot replace a Class’s prototype; the prototype chain (or tree, really) is isomorphic to the class hierarchy and is immutable.

Another difference, of course, is that you normally define fixed instance properties (variables and methods) when you write a Class. The fixed properties are placed in the class’s traits object, and the runtime checks the traits object for a property before searching the prototype chain; that is, class inheritance takes precedence over prototype inheritance. Fixed properties are typed, need not be public, and are found more quickly. As implied by the name, fixed properties cannot be deleted.

(You might think that the runtime has to search up the class hierarchy to find fixed properties that are inherited from a superclass. But in fact in AS3 these are copied down into the current class’s traits object, so they are found even more quickly.)

A Class’s constructor method is much like a constructor function. But you don’t get the chance to return anything from a constructor method, so new ClassName() will always return the new object. In fact you can’t even get a reference to the constructor method as a Function object, so you have no opportunity to try to invoke it without the new operator. This suggests that in AS3 the constructor method is still in a sense the same thing as the class.

I’m not going to get into the fascinating topic of closures right now, except to note that every function in AS and JS is a closure, so named because the scope of an inner function in these languages encloses the parameters and variables of the functions they are defined within.

Closures are first-class citizens of ActionScript. Every method in your class is a closure. That’s how it knows the instance variables of the class. Essentially every class is a big closure. You can write a function with closures inside that would be very much a class for all practical purposes.

– the RIA Book, p. 88

That last sentence describes what Douglas Crockford does in JavaScript: The Good Parts — what classical programmers may call simulating classes, and what Crockford calls better than classes.

Should you use dynamic features in your programming?

Sure, occasionally. Obviously, if you want to, you can create objects with a constructor function, then replace the constructor’s prototype, and create more objects with it.

If you think up a good use case for doing that, please let me know.

In fact, you should probably not use constructor functions at all. Crockford advises against them — and this in a language without user-defined classes! The lack of privacy is just one of the reasons he cites.

But you should definitely consider placing properties on class prototypes where appropriate.

UPDATE 22 Sept 2008: I now believe that the STRATEGY pattern is a better solution for this use case (see the comments on this post), but I’m leaving this example up as a demonstration of the technique for those who are interested.

Consider a game character who has a number of private methods; he wants to execute the appropriate method when he arrives at various targets, depending on the type of the target. He may have one method that he must execute whenever he arrives at any Flower, whether it be a Daisy or a Pansy or whatever derived class instance. If I set

Flower.prototype.myTask = flowerTask;

then on arrival, my character can call

target["myTask"]();

and the flowerTask is the one that will be executed if the target is any Flower derivative.

Here’s a little example; I’ve set properties on Target1.prototype and on Target2.prototype but not on Target3.prototype. Target2A is derived from Target2. Click on the targets:


An archive of the FlexBuilder project with sources and fuller explanation is here.

I like to think of prototype properties as a kind of enhanced reverse Dictionary; if you think of the property name as the data structure, and the object instances as keys — as though you were saying “myTask”[target] in the last example — then, when a certain value is set on a class’s prototype, you retrieve that value through any index that’s an instanceOf that class.

Further Reading

Steve Yegge: The Universal Design Pattern

AS3 Language Specification

Adobe Flex 3 Help -> Programming ActionScript 3.0 -> Object-oriented programming in ActionScript -> Advanced topics

Colin Moock: Essential ActionScript 3.0 Chapter 15, “Dynamic ActionScript”

Douglas Crockford: JavaScript: The Good Parts (get this book!)

Google Chrome Comic (JavaScript implementation and garbage collection)

Branden Hall and Samuel Wan: Object-Oriented Programming with ActionScript (historical interest; AS1 only)

Yakov Fain, Victor Rasputnis, and Anatole Tartakovsky: Rich Internet Applications with Adobe Flex & Java (Secrets of the Masters) (aka The RIA Book; especially Chapter 4, “Learning Flex Through Applications”)

Jens C Brynildsen: The Future of ActionScript

Derek Wischusen: Mixins in ActionScript 3 (perhaps going too far)

4 Comments »

  1. [...] I’ve looked into this and I have some answers to my own question: Dynamic Programming in AS3 | [...]

    Pingback by nodename » Advanced Users May Choose — September 19, 2008 @ 12:38 am

  2. Your example can easily be achieved by using the the Strategy pattern. This has the benefit of keeping your code clean, readable, strict-typed, fast and following good coding practices.

    Comment by Steven Sacks — September 19, 2008 @ 2:38 pm

  3. Thanks, Steven! I believe I’m convinced.

    No matter how you implement this, you need to be able to retrieve a discriminator (specifying what the Actor is to do) from a target instance. I was thinking that it was properly not a property of the target instance but rather of its class, and therefore, since static class properties are not inherited in AS3, the prototype would be good. But in fact making it an instance property of the target makes retrieval faster, and it’s also more general, because you can then set different discriminators in targets based on any criterion, not just the target’s class.

    Comment by alan — September 21, 2008 @ 11:05 pm

  4. I completely disagree. I don’t agree strategy pattern is appropriate… at least not in AS3… Why not just use event listeners? Add a listener and pass in a different function caller. This is also more powerful as let’s say in your strategy pattern (with the game) you would like to call two private methods. You can do that with events much cleaner…

    After reading your post (great btw, very informative and well explained), I don’t think that dynamic programming is worth the performance costs.

    I don’t know, maybe there’s some other weird pattern or instance where it’d work, maybe not… But def an interesting paradigm

    Comment by Danny Miller — September 23, 2008 @ 3:13 am

RSS feed for comments on this post. TrackBack URI

Leave a comment


Contents copyright © Alan Shaw 2005-2008

25 queries. 0.242 seconds. Powered by WordPress version 2.5.1