Prototype and as3

On twitter someone asked something which included the prototype property. With as1 I used (like all) prototype to extend and create new classes. With as2 class definitions changed completely and since then I stopped using prototype. I never thought about it, until someone mentioned it on twitter.

I became a bit curious about the prototype property and what its function is within as3; so I did some tests.

It seems Flash looks in prototype property when it can not find a method or variable name within the class (and super classes) definition or instance (in case of dynamic classes). If the prototype property does not contain the method or variable name, Flash will look in the prototype property of the super class (and so on).

The prototype is the last place looked in; so any definition in the class or super class will always come first. Flash also searches first within methods and variables added to a dynamic class instance during run-time.

The only useful thing I could think of so far is the ability to extend existing dynamic classes with methods and variables (not real properties, since there does not seem to be a way to add getter and setter methods). This looked promising, since with as1 I extended several base classes to include additional methods (like the Array, String and Math class). With as2 this was not longer possible and I created static helper classes instead.

Example:

Array.prototype.randomItem = function(): *
{
  return this[Math.floor(Math.random() * this.length)];
};
 
var list: Array = ["Red", "Orange", "Yellow", "Purple"];
 
trace(list.randomItem());
trace(list.randomItem());
trace(list.randomItem());

I was also curious if there would be a difference in calling methods stored in prototype and calling methods of a class/instance. For this i created the following class:

package
{
  public dynamic class One extends Object
  {
    public function One()
    {
      One.prototype.testFunction2 = function()
      {
        var dummy: int = Math.floor(Math.random() * 1000);
      };
 
      One.prototype.testFunction3VeryLongNameAtLeastTwiceAsMuchCharacters = function()
      {
        var dummy: int = Math.floor(Math.random() * 1000);
      };
    }
 
    public function testFunction1()
    {
      var dummy: int = Math.floor(Math.random() * 1000);
    }
  }
}

And then executed the following from a dummy movie within the Flash IDE:

var starttime: int 
var cnt: int;
var one: One = new One();
starttime = getTimer();
for(cnt = 0; cnt < 1000000; cnt++)
{
  one.testFunction1();
}
trace("time: " + (getTimer() - starttime));
starttime = getTimer();
for(cnt = 0; cnt < 1000000; cnt++)
{
  one.testFunction2();
}
trace("time: " + (getTimer() - starttime));
starttime = getTimer();
for(cnt = 0; cnt < 1000000; cnt++)
{
  one.testFunction3VeryLongNameAtLeastTwiceAsMuchCharacters();
}
trace("time: " + (getTimer() - starttime));

As result it turned out that last two loops took almost the double time as the first loop. The last two loops were very similar in duration; so there seems not to be any influence of the length of the function name.

It looks like using prototype has some downsides:

  • Only dynamic classes can be extended, one can not add methods to Math for example.
  • Calls to methods stored in the prototype take longer to execute (see test below)
  • Since methods are added run-time, editors can not show them with code hinting or use the correct syntax highlighting

I’ll probably will never use the prototype property, but maybe someone finds a good use for it.