Reputation: 51
This is complicated to explain but I've been on this for days now. I'm "extending" one Javascript "class" to another but calling a base-class method from a child-class method does not work properly. It seems as if the base-class-method "acts" as a static method : properties that are defined in the childclass somehow have their default values when calling a base-class-method from a-child-class method.
To keeps things simple I didn't include my elaborate code but created a simple example of what I'm doing:
function extend(Child, Parent){
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.base = Parent.prototype;
}
function BaseClass(){
}
BaseClass.prototype.randomNumber = 0;
BaseClass.prototype.functionA = function(){
this.randomNumber = 200;
this.functionB();
}
BaseClass.prototype.functionB = function(){
alert(this.randomNumber);
console.info(this);
}
function ChildClass(){
this.functionB = function(){
ChildClass.base.functionB();
};
}
extend(ChildClass, BaseClass);
var childInstance = new ChildClass();
childInstance.functionA();
I'm using firebug to log to the console. It output's "Baseclass" and this.randomNumber is somehow 0 while it is set to 200 in functionA.
the extend-method I'm using is simular to the one from Yahoo.lang.extend which I also tried with the same result.
I can't figure out if I'm missing something or this is just one of the drawbacks from "extending" Javascript and I'm actually calling a "static" method here. Help would be much appreciated here. Hope it's clear what I'm trying to do here because I find it complicated to put it in words. Thanks a lot in advance!
Upvotes: 2
Views: 1691
Reputation: 1075209
What happens in this line of code:
ChildClass.base.functionB();
...is that functionB
is called with this
pointing to ChildClass.base
. This is because this
, in JavaScript, is defined entirely by how a function is called, not where it's defined (unlike many other languages that have that keyword). To make that call whilst preserving the meaning of this
, you'd use call
:
ChildClass.base.functionB.call(this);
...which explicitly sets this
during the call to be whatever you pass in (this
, in this case). More: Mythical methods | You must remember this
By the way, if you're interested in inheritance hierarchies and making calls into the parent object (I won't say "class," JavaScript doesn't have classes), I wrote this up a few years ago: Simple, Efficient Supercalls in JavaScript It uses "class"-like terminology, which it really shouldn't (it's just helper methods to make hooking up hierarchies of prototypical inheritance easier), and it predates ECMAScript 5 (the latest version of JavaScript) which offers some features that would apply. So I need to update it, but it may be useful to you.
Upvotes: 5