How to call a parent method from child class in javascript?
Here's a nice way for child objects to have access to parent properties and methods using JavaScript's prototype chain, and it's compatible with Internet Explorer. JavaScript searches the prototype chain for methods and we want the child’s prototype chain to looks like this:
Child instance -> Child’s prototype (with Child methods) -> Parent’s prototype (with Parent methods) -> Object prototype -> null
The child methods can also call shadowed parent methods, as shown at the three asterisks *** below.
Here’s how:
//Parent constructor
function ParentConstructor(firstName){
//add parent properties:
this.parentProperty = firstName;
}
//add 2 Parent methods:
ParentConstructor.prototype.parentMethod = function(argument){
console.log(
"Parent says: argument=" + argument +
", parentProperty=" + this.parentProperty +
", childProperty=" + this.childProperty
);
};
ParentConstructor.prototype.commonMethod = function(argument){
console.log("Hello from Parent! argument=" + argument);
};
//Child constructor
function ChildConstructor(firstName, lastName){
//first add parent's properties
ParentConstructor.call(this, firstName);
//now add child's properties:
this.childProperty = lastName;
}
//insert Parent's methods into Child's prototype chain
var rCopyParentProto = Object.create(ParentConstructor.prototype);
rCopyParentProto.constructor = ChildConstructor;
ChildConstructor.prototype = rCopyParentProto;
//add 2 Child methods:
ChildConstructor.prototype.childMethod = function(argument){
console.log(
"Child says: argument=" + argument +
", parentProperty=" + this.parentProperty +
", childProperty=" + this.childProperty
);
};
ChildConstructor.prototype.commonMethod = function(argument){
console.log("Hello from Child! argument=" + argument);
// *** call Parent's version of common method
ParentConstructor.prototype.commonMethod(argument);
};
//create an instance of Child
var child_1 = new ChildConstructor('Albert', 'Einstein');
//call Child method
child_1.childMethod('do child method');
//call Parent method
child_1.parentMethod('do parent method');
//call common method
child_1.commonMethod('do common method');
Well in order to do this, you are not limited with the Class
abstraction of ES6. Accessing the parent constructor's prototype methods is possible through the __proto__
property (I am pretty sure there will be fellow JS coders to complain that it's depreciated) which is depreciated but at the same time discovered that it is actually an essential tool for sub-classing needs (especially for the Array sub-classing needs though). So while the __proto__
property is still available in all major JS engines that i know, ES6 introduced the Object.getPrototypeOf()
functionality on top of it. The super()
tool in the Class
abstraction is a syntactical sugar of this.
So in case you don't have access to the parent constructor's name and don't want to use the Class
abstraction you may still do as follows;
function ChildObject(name) {
// call the parent's constructor
ParentObject.call(this, name);
this.myMethod = function(arg) {
//this.__proto__.__proto__.myMethod.call(this,arg);
Object.getPrototypeOf(Object.getPrototypeOf(this)).myMethod.call(this,arg);
}
}
ES6 style allows you to use new features, such as super
keyword. super
keyword it's all about parent class context, when you are using ES6 classes syntax. As a very simple example, checkout:
Remember: We cannot invoke parent static methods via
super
keyword inside an instance method. Calling method should also be static.
Invocation of static method via instance method - TypeError !
class Foo {
static classMethod() {
return 'hello';
}
}
class Bar extends Foo {
classMethod() {
return super.classMethod() + ', too';
}
}
console.log(Bar.classMethod()); // 'hello' - Invokes inherited static method
console.log((new Bar()).classMethod()); // 'Uncaught TypeError' - Invokes on instance method
Invocation of static method via super
- This works!
class Foo {
static classMethod() {
return 'hello';
}
}
class Bar extends Foo {
static classMethod() {
return super.classMethod() + ', too';
}
}
console.log(Bar.classMethod()); // 'hello, too'
Now super
context changes based on invocation - Voila!
class Foo {
static classMethod() {
return 'hello i am static only';
}
classMethod() {
return 'hello there i am an instance ';
}
}
class Bar extends Foo {
classMethod() {
return super.classMethod() + ', too';
}
}
console.log((new Bar()).classMethod()); // "hello there i am an instance , too"
console.log(Bar.classMethod()); // "hello i am static only"
Also, you can use super
to call parent constructor:
class Foo {}
class Bar extends Foo {
constructor(num) {
let tmp = num * 2; // OK
this.num = num; // ReferenceError
super();
this.num = num; // OK
}
}
And of course you can use it to access parent class properties super.prop
.
So, use ES6 and be happy.
Here's how its done: ParentClass.prototype.myMethod();
Or if you want to call it in the context of the current instance, you can do:
ParentClass.prototype.myMethod.call(this)
Same goes for calling a parent method from child class with arguments:
ParentClass.prototype.myMethod.call(this, arg1, arg2, ..)
* Hint: use apply()
instead of call()
to pass arguments as an array.