简体   繁体   中英

Cannot use child class' properties within parent class constructor via Babel's transform-class-properties

When extending a parent class and declaring the child class' properties via Babel's 'transform-class-properties' plugin, any class properties of the child class are not accessible via the parent class' constructor method.

class One {

    internal = 1;

    constructor() {
        console.log('constructor internal', this.internal);
    }

}

class Two extends One {

    internal = 2;

}

new Two();

In the example above, 'constructor internal 1' will be output to the console. When looking at the compiled code this is obvious as to why, with the parent class being executed first and the resulting object then being integrated with the child class.

Apologies if this is by design, but it has confused me as the following code works in the way I am expecting within non-constructor methods (so the boot() method references the child class' 'internal' property value):

class One {

    internal = 1;

    constructor() {
        console.log('constructor internal', this.internal);
    }

    boot() {
        console.log('boot internal', this.internal);
    }

}

class Two extends One {

    internal = 2;

    constructor() {
            super();

            this.boot();
    }

}

new Two();

So, even when calling a method declared on the parent class, it will inherit the child class' properties. It is just constructor methods which seemingly do not behave as expected (at least by me - again, apologies if this is wrongly interpreted, but there are no caveats listed on the relative Babel page.)

Thank you.

I think that is natural. If you wish to override the parent class's property init value, you should do it in the derived class's constructor.

class Two extends One {

    constructor() {
        // Call parent constructor.
        super();
        // Override here.
        this.internal = 2;
    }

}

Hope it helps. Happy coding (:

loganfsmyth answered my question very clearly here: https://phabricator.babeljs.io/T7567 (Thanks!)

This is indeed expected behavior. Babel's implementation is a little incorrect because in a perfect world this would also throw an error, because you shouldn't have the same property defined in a parent and a child, but we don't do that right at the moment.

Class properties are initialized when:

  • For base classes, before the constructor executes

  • For child classes, at the end of super()

and when a given constructor initializes it's bindings, it uses that classes bindings, it doesn't know of anything in child classes. That means your One class knows the value should be 1, so that's what it sets.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM