So I tested this code:

class C1 {}

C1.prototype. f =function(){ return 1 }

class C2 extends C1 {}

C2.prototype. f =function(){ return super.f()+1 }

And it throws a syntax error: 'super' keyword unexpected here.

But if I do:

C2.prototype. f =function(){ return Object.getPrototypeOf(this.constructor.prototype).f() + 1 }

It does return a two!

So does anyone know why 'super' doesn't work? I see no reason for it.

Thanks!

2

There are 2 best solutions below

0
On BEST ANSWER

Object.getPrototypeOf(this.constructor.prototype).f() loses the instance:

class C1 {
    constructor(x) {
        this.x = x;
    }

    f() {
        console.log(this.x);
    }
}

class C2 extends C1 {
    f() {
        Object.getPrototypeOf(this.constructor.prototype).f();
    }
}

new C1(42).f();  // 42
new C2(42).f();  // undefined

(because this === C1.prototype when a function is called as C1.prototype.f())

Object.getPrototypeOf(this.constructor.prototype).f.call(this) always has this.constructor as the bottom of the class hierarchy, which breaks when you add a level:

class C1 {
    constructor(x) {
        this.x = x;
    }

    f() {
        console.log(this.x);
    }
}

class C2 extends C1 {
    f() {
        Object.getPrototypeOf(this.constructor.prototype).f.call(this);
    }
}

class C3 extends C2 {}

new C1(42).f();  // 42
new C2(42).f();  // 42
new C3(42).f();  // infinite recursion

A correct version for reasonable code would be

Object.getPrototypeOf(/* containing class */.prototype).f.call(this)

which is basically what super does – and for that, it needs to know the containing class (or object), which doesn’t necessarily exist for arbitrary function expressions.

3
On

super is a keyword meaning it must be accepted by the interpreter and currently only class can use it. You must backup your method or refer to it remotely if you want the same effect:

class C1 {}

C1.prototype. f =function(){ return 1 }

class C2 extends C1 {}

C2.prototype. f =function(){ return C1.prototype.f.call(this)+1 }