I'm writing an object hierarchy in JavaScript, I would like to call a method on an object's parent when I've shadowed that method in the object.
E.g.:
var Base = function Base(msg) {
this.msg = msg;
}
Base.prototype.log = function(){
console.log("base log: " + this.msg);
}
var Sub = function Sub(msg) {
Base.call(this, msg);
}
Sub.prototype = Object.create(Base.prototype);
Sub.prototype.log = function() {
console.log("sub log");
this.__proto__.__proto__.log.call(this); // This works but __proto__
Object.getPrototypeOf(Object.getPrototypeOf(this)).log.call(this); // This works but is verbose
super.log(); // This doesn't work
}
var sub = new Sub('hi');
sub.log();
See the three lines at the bottom of the Sub.prototype.log
function - is there a better way to do what I'm trying to do there?
The second line is the best I've been able to come up with but is very verbose!
When it comes to inheritance, JavaScript only has one construct: objects. Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype.
In JavaScript, there is the ability to create a generic anonymous object to serve this purpose. It can either be created using new Object() or the shorthand { ... } syntax, and can then be given any properties or methods that are needed.
Class methods are created with the same syntax as object methods. Use the keyword class to create a class. Always add a constructor() method. Then add any number of methods.
The instanceof operator in JavaScript is used to check the type of an object at run time. It returns a boolean value if true then it indicates that the object is an instance of a particular class and if false then it is not.
super
is not defined, obviously it wouldn't work.
You might want to try:
Sub.prototype.log = function() {
console.log("sub log");
Base.prototype.log.call(this);
}
Another way is to use the following method to inherit classes:
function extend(Child, Parent) {
var F = function() { };
F.prototype = Parent.prototype;
Child.prototype = new F();
// better to make it static (better practice in OOP world)
// e.g. Child.super = ...,
// but in your case:
Child.prototype.super = Parent.prototype;
}
So here is an example:
// ..
extend(Sub, Base);
Sub.prototype.log = function() {
console.log("sub log");
this.super.log.call(this);
}
In case of ES6
:
class Base {
constructor(msg) {
this.msg = msg;
}
log(){
console.log("base log: " + this.msg);
}
}
class Sub extends Base {
constructor(msg) {
super(msg);
}
log() {
console.log("sub log");
super.log();
}
}
var sub = new Sub('hi');
sub.log();
If you want to keep the original method without using the name Base
you could capture it using a closure before you change it.
(function() {
var superLog = Sub.prototype.log;
Sub.prototype.log = function() {
console.log("sub log");
superLog();
};
})();
This way there is no dependancy on how you inherit from Base
.
Side note: the terminology you are looking for is 'overriding' the base method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With