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.