Add methods to native Classes in ActionScript 3.0 – Prototype functions

Hi again!
Yesterday I’ve found out a cool new feature of ActionScript 3.0. You will sometimes have to use associative Arrays. The problem with these is that you can’t easily loop through them with a for-loop like

ActionScript
var  myAssocArray:Array = [],
    i      :int,
    intLength  :int;
 
myAssocArray['foo'] = 'one';
myAssocArray[1] = 'two';
myAssocArray['bar'] = 'three';
myAssocArray[0] = 'four';
intLength = myAssocArray.length;
 
for(; i< intLength; ++i)
{
  trace(myAssocArray[i]);
}

The trace will probably print out “four, two, undefined, undefined”. The fact is that you can get the elements 0 & 1 via the variable i, but the the other keys can’t be accessed with this method.
As I also like PHP very much, I also know the function array_keys(array) of PHP, which returns the key-values of the array given in the parameters. I thought that I really need this functionality within AS3, so I tried a lot, searched the internet and finally got it! It’s pretty simple for those knowing AS2 – prototype functions.
What do we need to do? Place the following code in your main, unnamed package below or above the class-definition and you can use it everywhere else in the code:

ActionScript
package
{
  public class foo
  {
    public function foo():void
    {
      trace('bar');
    }
  }
 
  Array.prototype.arrayKeys = function():Array
  {
    var  arrReturn  :Array = [],
      strKey    :String;
 
    for(strKey in this)
    {
      if(typeof this[strKey] == 'function') continue;
      trace('in Array:: value->'+ strKey +' typeOf:'+ typeof strKey +' proto:'+ ((this[strKey] !== false) ? typeof this[strKey] : 'NULL'));
      arrReturn[arrReturn.length] = strKey;
    }
 
    return arrReturn;
  }
 
  Number.prototype.give = function():String
  {
    return 'Number::giveItToMeBaby';
  }
}

You can now use this method to get the keys of the variable:

ActionScript
var arrKeys    :Array = myAssocArray.arrayKeys(),
  i      :int,
  intLength  :int = arrKeys.length;
 
for(; i < intLength; ++i)
{
  trace(myAssocArray[arrKeys[i]]);
}

Pretty easy, isn't it? Well, it is easy because the native Array-Class is dynamic, but what do we do with Number (final class)? Let's see...

ActionScript
var num:Number = 4;
num.give(); //doesn't work! final class, can't add methods to it?
 
num['give'](); //does work :) you can dynamically add methods to a class even if it's final; problem is that this code is hard to read, but it actually works

So far...
Daniel

Comments (3)

  1. 16:14, 12. August 2009Daniel Bunte  / Reply

    Please note:

    The problem with Array-Prototype-Methods is that if you run through that array with
    for(var strKey:* in arrObjects)
    {
    trace(strKey);
    }

    you will probably also get the function as a methdod.
    So the trace will will put “function() Function” or something similar on the screen.

  2. 13:14, 27. October 2010wonderwhy-er  / Reply

    Pretty cool. Sad you can’t kind of override stuff with this. But that probably would be too much of a mess.
    I actually wonder what kind of mess that could turn in to if various libs would start adding their own methods to core classes ending up having name conflicts…

    It seems it is also impossible to add check/warning to case when prototype already has some method.

  3. 13:44, 27. October 2010Daniel Bunte  / Reply

    i wrote this only to show what’s possible. it’s of course not a good programming practice using prototyping, but may help on different problems.

Leave a Reply

Allowed Tags - You may use these HTML tags and attributes in your comment.

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

Pingbacks (0)

› No pingbacks yet.