I thought I had a good understanding on how to properly extend classes in JavaScript, but when extending a subclass I run into an endless loop when I override a method, and the call the parent method from the child class. I'm either doing it wrong, or you just shouldn't subclass this way in JavaScript.
Can anybody help educate me please?
var Grand = function() {
this.test();
};
Grand.prototype.constructor = Grand;
Grand.prototype.test = function() {
console.log( "Grand!")
};
var Parent = function() {
this.supr.constructor.call( this );
};
Parent.prototype = Object.create( Grand.prototype );
Parent.prototype.constructor = Parent;
Parent.prototype.supr = Grand.prototype;
Parent.prototype.test = function() {
this.supr.test.call( this );
console.log( "Parent!" );
};
var Child = function() {
this.supr.constructor.call( this );
};
Child.prototype = Object.create( Parent.prototype );
Child.prototype.constructor = Child;
Child.prototype.supr = Parent.prototype;
Child.prototype.test = function() {
this.supr.test.call( this );
console.log( "Child!" );
};
var g = new Grand(); // Outputs "Grand!"
var p = new Parent(); // Outputs "Grand!" "Parent!"
var c = new Child(); // Error: Endless Loop!
I would expect the console to log "Grand!", "Parent!", "Child!" when instantiated a new Child(), but instead I get an endless loop.
I'm coming from an ActionScript background, so creating classes in JavaScript still throws me some curve balls. Thanks for the help in advance!
The problem is with this bit of code:
Consider what happens when this code executes:
Here
this
is the variablec
, sothis.supr.constructor
will always be the parent's constructor as setup in these lines of code:So, when the Child's constructor invokes
this.supr.constructor.call( this );
it executes theParent
function, and the parent function again executesthis.supr.constructor.call( this );
resulting theParent
function being invoked again, causing the endless loop.A fix is to invoke base class functions as follows:
More details in this post
I recommend switching to es6. This prototyping can be a real mess and is harder to keep track of. But then if you need this in the browser, you should transpile your code to es5 whit babel or such. In the Node env its fine without as long as you have a recent up to date version. Some of the latest browser supports it as well
Not only is it more readable, but it's less code and more understandable