Calling an overridden static method from parent

However I haven't found any documentation saying one way or the other about referring to a static method overridden by a child class, so the question is, can I rely on this always being so?

It's the standard function-call-via-object-property mechanism. When you do:

Child1.doImportantStuff();

...unless doImportantStuff is an arrow function (it isn't) or a bound function (it isn't), then during the call, this is set to Child1. Exactly like:

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

So yes, you can rely on that. (And I understand why you asked, it does seem a bit odd unless you work it through.)

Of course, it won't work from within the code of a non-static function, because this will refer to the instance, not the constructor function. If you needed it there, you could use this.constructor.doImportantStuff unless someone's messed up the constructor property. (People always used to mess it up; with the new syntax automating it, hopefully that will happen less although it's rare you really need it...)


For these kinds of questions, it's frequently 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 thorough). It's really good sugar, but that's nearly all it is (and that's a Good Thing™). static methods are set as properties of the constructor function, non-static methods are set up as properties of the object on the constructor's prototype property. (I think the only non-sugar aspect of it is, as Bergi points out, that the new syntax lets us extend builtins like Array which it wasn't possible to do before. Part of making that possible relates to how and when this gets set up [you can't access it prior to the super() call in your subclass constructor], which relates to new.target, which Bergi discusses here. In ES7, it may go further beyond sugar with privacy stuff.)


If you don't want to call

Child1.doImportantStuff();

in Parent, but rather dynamically invoke 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'