Trying to understand how inheritance can be done in Javascript, I stumbled across many differerent implementations, including Crockfords, Resigs, Prototype
, klass
, and others.
What I missed (I brace myself for the uproar) was the Smalltalkish self/super pair: self
playing a similar role than this
, namely representing the current "object", and super
referring to a superclass-only version of this
.
[Skip to "]" if you know what super
does in Smalltalk: Assuming Subclass
has overriden method1
defined in Superclass
, I can still access the superclass implementation using super.method1()
in Subclass.method2()
. This will not execute the Subclass.method1()
code.
function Superclass () {
}
Superclass.prototype.method1 = function () {
return "super";
}
function Subclass () {
}
Subclass.prototype.method1 = function () {
return "sub";
}
Subclass.prototype.method2 = function () {
alert (super.method1 ());
}
var o = new Subclass;
o.method2 (); // prints "super"
]
Is there any "Javatalk" package out there? So far, I have seen only OO emulations in Javascript which give access to the superclass implementation of the currently defined method (method2
), not any other (such as method1
).
Thanks, nobi
There are so many ways to implement a super
feature in JavaScript. For instance:
function SuperClass(someValue) {
this.someValue = someValue;
}
SuperClass.prototype.method1 = function () {
return this.someValue;
};
function SubClass(someValue) {
//call the SuperClass constructor
this.super.constructor.call(this, someValue);
}
//inherit from SuperClass
SubClass.prototype = Object.create(SuperClass.prototype);
//create the super member that points to the SuperClass prototype
SubClass.prototype.super = SuperClass.prototype;
SubClass.prototype.method2 = function () {
alert(this.super.method1.call(this));
};
var sub = new SubClass('some value');
sub.method2();
EDIT:
Here's an example of an extremely generic super
method that relies on non-standard features. I really do not recommend this and it's just there as learning purposes.
Object.prototype.super = function () {
var superProto = Object.getPrototypeOf(Object.getPrototypeOf(this)),
fnName = arguments.callee.caller.name,
constructorName = this.constructor.name;
if (superProto == null) throw constructorName + " doesn't have a superclass";
if (typeof superProto[fnName] !== 'function') {
throw constructorName + "'s superclass ("
+ superProto.constructor.name + ") doesn't have a " + fnName + ' function';
}
return superProto[arguments.callee.caller.name].apply(
this,
[].slice.call(arguments, 1)
);
};
function A() {
}
A.prototype.toString = function toString() {
//call super method Object.prototype.toString
return this.super();
};
var a = new A();
console.log(a.toString());