Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arrow function called within super class constructor #1717

Closed
andrewvarga opened this issue Jan 18, 2015 · 1 comment
Closed

Arrow function called within super class constructor #1717

andrewvarga opened this issue Jan 18, 2015 · 1 comment
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead

Comments

@andrewvarga
Copy link

I have a problem I've encountered a few times:

class BaseClass
{
    constructor()
    {
        this.init();
    }

    protected init()
    {
    }
}

class ChildClass extends BaseClass
{
    constructor()
    {
        super();
    }

    protected init()
    {
        var div = document.createElement("div");
        console.log(this.onClick); // undefined
        div.addEventListener("click", this.onClick);
    }

    private onClick = (event: MouseEvent) =>
    {
        // ...
    }
}

var child = new ChildClass();

The problem is that in the init of ChildClass, "onClick" is still undefined because in the compiled JS it is only defined after the super call. This comes up generally when I call functions in the super class that are likely to be overridden in child classes and the child implementations use arrow functions defined in the child class.

I was wondering what was the reason behind this order and wouldn't it be possible to reverse it (ie. define arrow functions first, call super afterwards).
I think it's related to this error message which pops up if you try to call init manually before super():

"A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties"

Related issues are:
https://typescript.codeplex.com/discussions/444975
http://typescript.codeplex.com/workitem/91

My view of this is that the only reason I'm using arrow functions generally is to make sure the scope (this) is correct, so ideally it would be good to be able to work with them just like if they were "non-arrow", normal prototypical functions.

@RyanCavanaugh RyanCavanaugh added the By Design Deprecated - use "Working as Intended" or "Design Limitation" instead label Jan 20, 2015
@RyanCavanaugh
Copy link
Member

There isn't any sensible way to redefine the order of initialization of a TypeScript class. See #1617 for an extended explanation of how class emit and other constraints prevent any other initialization order than the one you see today.

More generally, the principle of "don't call virtual methods from constructors" remains good OOP advice.

@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead
Projects
None yet
Development

No branches or pull requests

2 participants