Calling the overridden static method from the parent

Firstly, some code to set the scene:

var instances = []; class Parent { static doImportantStuff() { console.log( 'Parent doing important stuff' ); return false; } static init() { if ( this.doImportantStuff() ) instances.push( new this() ); } } class Child1 extends Parent { static doImportantStuff() { console.log( 'Child 1 doing important stuff' ); if (someCondition) return true; return false; } } class Child2 extends Parent { static doImportantStuff() { console.log( 'Child 2 doing important stuff' ); if (someOtherCondition) return true; return false; } } 

The idea is that there is a Parent class that extends with several Child classes. The initialization of the Child classes is basically the same, but each of them has its own implementation of doImportantStuff() , whose return value indicates whether the Child instance should be created.

So far, this has worked in every transporter I tried, because this in the Parent.init() function refers to the constructor of the Child class. However, I did not find any documentation saying anyway about the mention of a static method overridden by a child class, so the question is, can I always rely on this so? Or is there another way to do this?

+8
javascript ecmascript-6
source share
2 answers

However, I did not find any documentation that said in any way that it refers to a static method overridden by a child class, so the question is, can I always rely on this?

This is the standard function-call-through-object-property mechanism. When you do:

 Child1.doImportantStuff(); 

... if doImportantStuff not an arrow function (this is not) or a related function (this is not), then during the call this set to Child1 . Similar:

 var obj = { foo: function() { console.log(this === obj); } }; obj.foo(); // "true" 

So you can rely on that. (And I understand why you asked, it seems a little strange if you don't work it out.)

Of course, it will not work from non- static function code, because this will refer to the instance, and not to the constructor function. If you need it, you can use this.constructor.doImportantStuff if someone hasn't messed up the constructor property. (People are always used to messing it up, with the new syntax automating it, we hope this happens less, although you rarely need it ...)


For such questions, it is often useful to remember that the new class syntax is almost just syntactic sugar for the old verbose way we did it (if we were really solid). It is really good sugar, but that's almost all (and it's a good thing). static methods are set as properties of a constructor function, and not static methods are set as properties of an object in the prototype constructor property. (I think the only non-sugar aspect of this is that Bergi indicates that the new syntax allows us to extend built-in functions, such as Array , that werenโ€™t possible to do this before. Some of the possible connection is related to how and when this set [you cannot access it until you call super() in your subclass constructor], which refers to new.target , which Bergi is discussing here . In ES7, it can go beyond sugar using confidential materials.)

+8
source share

If you do not want to call

 Child1.doImportantStuff(); 

in Parent , but rather dynamically call the overridden static method, you can do:

 this.constructor.doImportantStuff(); 

This also works for setters and in the constructor of the parent class:

 class Parent { static get foo() { // Throw an error to indicate that this is an abstract method. throw new TypeError('This method should be overridden by inheriting classes.'); } constructor() { console.log(this.constructor.foo); } logFoo() { console.log(this.constructor.foo); } } class Child extends Parent { static get foo() { return 'yay'; } } const child = new Child(); // Prints 'yay' child.logFoo(); // Prints 'yay' 
+3
source share

All Articles