I have some classes (constructors) that are related as "parent-child":
// Abstract root SuperClass
function SuperClass() {
this.CLASS_ID = "SUPER-CLASS";
throw new Error('Failed to instantiate abstract class' + this.CLASS_ID);
}
SuperClass.prototype.sayHello = function() {
alert('Hello, world!');
};
// Absctract ClassA inherits from SuperClass
// inherit() and extend() are generic functions from the David Flanagan`s
// brilliand book "Definitive Guide"
function ClassA() {
this.CLASS_ID = "CLASS-A";
throw new Error('Failed to instantiate abstract class' + this.CLASS_ID);
}
ClassA.prototype = inherit(SuperClass.prototype);
// Concrete ClassB inherits from ClassA
function ClassB(initData) {
this.CLASS_ID = "CLASS-B";
}
ClassB.prototype = inherit(ClassA.prototype);
extend(ClassB.prototype, {
constructor: ClassB,
welcomeNewDay: function() {
this.sayHello();
this.doSomethingElse();
},
doSomethingElse: function(){
alert('Jumping');
}
});
var classB = new ClassB();
classB.welcomeNewDay();
How can I correctly extend method .sayHello()
of the abstract ClassA
without overloading it?
I`ve tried to make it this way:
extend(ClassA.prototype, {
sayHello: function() {
this.__proto__.sayHello();
this.sing();
},
sing: function() {
alert('Lalala');
}
});
The problem is that .sing()
is invoked 3 times instead of 1.
If I try:
this.__proto__.sayHello.call(this);
It throws an exception:
Uncaught RangeError: Maximum call stack size exceeded
Try to access the initial class:
extend(ClassA.prototype, {
sayHello: function() {
SuperClass.prototype.sayHello.call(this);
this.sing();
},
sing: function() {
alert('Lalala');
}
});
or just store the current sayHello()
method:
var initialSayHello = ClassA.prototype.sayHello;
extend(ClassA.prototype, {
sayHello: function() {
initialSayHello.call(this);
this.sing();
},
sing: function() {
alert('Lalala');
}
});
You need to have the reference to the original sayHello()
method.
Uncaught RangeError: Maximum call stack size exceeded
It is thrown because you actually have an infinite recursion, calling the method itself in the method.