In contrast to class-oriented languages JS is prototype-based and the constructor of an object does not only contain the "constructor logic" (I found this term at MDN) but the constructor also defines the privileged methods. In the case that one "class" is the child of another class (sorry I do not know a better term than "class" for JS) this leads to the problem that either the parent constructor is executed before the child class is able to override a method or that the child class is not able to override a method, because the constructor has not run yet.
I will give an example to illustrate what I mean. Assume a "parent class" that defines a privileged function on the object and a constructor logic that calls this method.
function Parent() {
this.methodA = function() {
// do something
};
// C'tor logic starts here
// Beside other things also call some method of this object
this.methodA();
}
Assume a child class that shall redefine methodA
but still use the
constructor logic of the parent class.
The first approach is to call the parent constructor at the beginning of the child constructor. However, then the parent constructor still calls the implementation of the parent.
Child.prototype = Object.create( Parent.prototype );
Child.prototype.constructor = Child;
function Child() {
// Call parent constructor first. Problem: The parent constructor
// calls methodA before it will be overriden by child constructor
Parent.call( this );
var _oldMethodA = this.methodA;
this.methodA = function() {
// do something special and then call parent method
_oldMethodA.call( this );
};
}
The second approach is to call the parent constructor later, however, then the parent method cannot be overridden.
Child.prototype = Object.create( Parent.prototype );
Child.prototype.constructor = Child;
function Child() {
// Override first. Problem: The parent constructor has not defined methodA
// yet, hence the line below fails.
var _oldMethodA = this.methodA;
this.methodA = function() {
// do something special and call parent method
_oldMethodA.call( this );
};
Parent.call( this );
}
How do I interleave the both tasks of JS constructor - definition of privileged methods and constructor logic - are called in correct order?
Appendix - Additional material due to comments
I figured out from the comments that it seems not to be clear what I want. So here is an example written in Java
class Parent {
public Parent() {
methodA();
}
public void methodA() {
System.out.println( "I do the work of the parent's method" );
}
}
class Child extends Parent {
public Child {
super();
}
public void methodA() {
System.out.println( "I do the work of the child's method and ..." );
super();
}
}
Parent p = new Parent();
Child c = new Child();
This results in the following output
$> I do the work of the parent's method
$> I do the work of the child's method and ...
$> I do the work of the parent's method
This is what happens. The constructor of Parent
calls the implementation of methodA
as defined in Parent
. This is nothing special and produces the first line of output. The constructor of Child
just calls the parent's constructor that again calls methodA
as before. However, although this is the parent's constructor the object is still an instance of Child
hence the implementation of methodA
of the child class is executed. This method prints the 2nd line of output and then explicitly calls the parent's method that produces the 3rd line.
This is perfect correct behavior according to OOP and this is what I want to achieve with Javascript, too. So it is actually the opposite of the problem mentioned here. The link is from the comments.