Justin van Schaick
Justin van Schaick

Reputation: 51

Javascript class extension : calling base class-function from child-class function : seem to be calling static method

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

Answers (1)

T.J. Crowder
T.J. Crowder

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

Related Questions