In AS2, you can pass parameters to a super class’s constructor using super() . This is handy, but what if your constructor accepts an undefined number of parameters, and you want to pass them all to your super constructor (think of the Array class, for instance)? Sounds easy – you should just be able to use “super.apply(this,arguments)”, right? Wrong…
BEGIN EXTENDED ENTRY
In AS2, you can pass parameters to a super class’s constructor using super() like so:
class MySubClass extends MySuperClass { function MySubClass(p_param) { super(p_param); } } |
This is handy, but what if your constructor accepts an undefined number of parameters, and you want to pass them all to your super constructor (think of the Array class, for instance)? Sounds easy – you should just be able to use “super.apply(this,arguments)”, right?
Wrong. Two things get in the way:
- The compiler does not interpret “super” as being a function, and will return “There is no method with the name ‘apply’.”
- Because the compiler can’t find a call to super() in the sub class constructor (it isn’t smart enough to understand super.apply()), it inserts an empty super() call at the beginning of the sub class constructor, so even if you get super.apply to work, the constructor will be called twice!
I wrestled with this issue for a bit, then talked it through with Jonas Galvez, who came up with a solution. It’s a bit hackish, but it works! Here’s what it looks like:
class MegaArray extends Array { function MegaArray() { super; // tricks the compiler __proto__.constructor.apply(this, arguments); } } |
Basically, it tricks the compiler into thinking we have called the super class’s constructor, then we really call it using apply.
Just don’t try spelling constructor as “contructor”, or you’ll spend 20 minutes wondering why the heck it doesn’t work! 😛
Nice work Jonas!
EDIT: Sometimes you look too hard and make things more complex than they have to be… It looks as though this will work too (thanks David):
class MegaArray extends Array { function MegaArray() { super.constructor.apply(this, arguments); } } |
yo, nice discovery. played with it a lil and found super.constructor.apply(this, arguments); seems to work too.
super.constructor actually makes grammatical/logical sense as well. Nice.
I have to say that this doesnt work at all for me, If I extend the Array class and then try and do what you describe above, then my array is empty.
the same happened to me for array inheritance.
here’s a work arround
[as]class myClass extends Array{
function WindowsAdmin(){
for(var i=0;i<arguments.length;i++){
this.push(arguments[i]);
}
}
}[/as]
Hi Sangles and Chris,
You must call the Array constructor, as follows:
class SuperArray extends Array {
function SuperArray() {
super.constructor.apply(this, arguments);
}
}
Jonas, it doesn´t work.
try:
var ma:MegaArray = new MegaArray(1,2,3,4);
trace(ma[2]);
the result is undefined, not 3.
The first approach doesn´t look to work either(?)
cheers,
Florian
how about this,
super.constructor.apply(null,arguments);
that way the super constructor will execute in the super scope as opposed to “this” scope.
-Butt
played with this recently… and its not working… i wonder what’s causing this to work on some system and fail on others 🙁
Doesn’t work for me to ?
Is there a work around ?
Thanks
If the superclass is inherited from another class, will the super.constructor.apply instruction work, despite of the “constructor bug” ?!?
http://chattyfig.figleaf.com/ezmlm/ezmlm-cgi?1:mss:90588
super.constructor.apply(this, arguments);
works for me.
My superclass is not a subclass of any other class.
Thanks!
Using this as an argument can cause infinite recursion when used with long inheritance chains (I’m pretty sure it always refers to the top level object). This seems to work much better…
super.constructor.apply( super, arguments );
…super is a strange thing!