I've been learning about classes in JavaScript, the use of prototype and finally how to inherit.
From my understanding the below should:
- Alert "John" due to
myInstance.getIt();being called - Alert "Jack" due to
myInheritedInstance.getIt();being called myInheritedInstance.getParent();has been assigned to.getIt()in MyClass- This should then alert "John" when myInheritedInstance.getParent(); is called.
Instead what actually happens is:
- Alert "John"
- Alert Blank
- Alert "Jack"
I have a feeling I've done something stupid or have misunderstood a fundamental concept here, so any help would be appreciated.
var MyClass = function() { };
MyClass.prototype.constructor = MyClass;
MyClass.prototype.name = "John";
MyClass.prototype.getIt = function () { alert(this.name); };
var myInstance = new MyClass();
myInstance.getIt();
//Now inheritance
var MyInheritedClass = function () { };
MyInheritedClass.prototype = new MyClass;
MyInheritedClass.prototype.constructor = MyInheritedClass;
MyInheritedClass.prototype.name = "Jack";
MyInheritedClass.prototype.getIt = function () { alert(this.name); };
MyInheritedClass.prototype.getItParent = MyClass.prototype.getIt.call(this);
var myInheritedInstance = new MyInheritedClass();
myInheritedInstance.getIt();
myInheritedInstance.getItParent();
1 Answer 1
The culprit is:
MyInheritedClass.prototype.getItParent = MyClass.prototype.getIt.call(this);
.call will call a function, not return one. So it will cause two issues: it calls it beforehand, and returns something that isn't callable (you get an error in the console). You'd have to do:
MyInheritedClass.prototype.getItParent = function() {
alert(Object.getPrototypeOf(Object.getPrototypeOf(this)).name);
};
The problem is that name is not accessible through this anymore as it has been shadowed over by the inherited class. To get name of the original class, you have to walk up the prototype chain two times: inherited instance -> inherited prototype -> original prototype.
The line
MyClass.prototype.constructor = MyClass;
isn't necessary here, by the way. Restoring constructor is necessary in case you overwrite prototype, because constructor gets lost in that case. So in your case, it is necessary only for the inherited class.
Also, the line
MyInheritedClass.prototype.getIt = function () { alert(this.name); };
is superfluous, it's just the same as MyClass.prototype.getIt - which you inherited.
Note that JavaScript does not have real "classes", although their behaviour can be accomplished like this.