Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript constructors which return an object implicitly substitute the value of `this` for any callers of `super(...)`?

Tags:

typescript

I'm trying to understand a line in the handbook:

In ES2015, constructors which return an object implicitly substitute the value of this for any callers of super(...). It is necessary for generated constructor code to capture any potential return value of super(...) and replace it with this.

The entire line is vague for me. Can someone explain what happened here?

like image 837
Rainning Avatar asked Dec 30 '25 09:12

Rainning


1 Answers

The super "function call" is weird. For normal classes that don't return objects, this is just the current instance of the class being constructed. The call to super() just operates on the same this, and so the final constructed object is an instance of the subclass:

class Foo {
    a = 10;
    constructor() { }
}

class Bar extends Foo {
    z: number;
    constructor() {
        super();
        this.z = 1;
    }
}

const b = new Bar();
console.log(b); // Bar: {a: 10, z: 1}
console.log(b instanceof Bar); // true

But if the superclass returns a value from its constructor, then somehow this in the subclass becomes that value. That allows subsequent references to this to refer to the same object that the superclass returns. So the subclass behaves "normally" except that the constructed object isn't actually an instance of the class:

class Foo {
    constructor() {
        return { a: 10 };
    }
}

class Bar extends Foo {
    z: number;
    constructor() {
        super();
        this.z = 1;
    }
}

const b = new Bar();
console.log(b); // {a: 10, z: 1}
console.log(b instanceof Bar); // false

That means the call to super() has to look like "call the superclass constructor like a function, sort of, and see if it returns anything". If so, then assign the result of that function to this. As if you could write

this = superCtor.call(this) || this;

But you can't do that! You can't assign to this. But it happens anyway, implicitly. If you look at what happens when super constructors are called when downleveling code to a version of JS before class existed, you'll see something similar:

function Bar() {
    var _this = _super.call(this) || this;
    _this.z = 1;
    return _this;
}

And you see that the actual this has been replaced with a new _this variable everywhere.

Playground link to code

like image 192
jcalz Avatar answered Jan 01 '26 00:01

jcalz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!