不能通过Babel的transform-class-properties在父类构造函数中使用子类的属性

时间:2016-08-23 11:31:31

标签: javascript class constructor babeljs ecmascript-next

当扩展父类并通过Babel的'transform-class-properties'插件声明子类的属性时,子类的任何类属性都不能通过父类的构造函数方法访问。

class One {

    internal = 1;

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

}

class Two extends One {

    internal = 2;

}

new Two();

在上面的示例中,'constructor internal 1'将输出到控制台。在查看已编译的代码时,这显然是为什么,首先执行父类,然后将结果对象与子类集成。

道歉,如果这是设计的,但它让我感到困惑,因为下面的代码按照我在非构造函数方法中期望的方式工作(因此boot()方法引用子类''internal'属性值):

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();

因此,即使调用在父类上声明的方法,它也将继承子类的属性。它只是构造函数方法,似乎没有按预期行事(至少我是 - 再次,如果这被错误地解释,道歉,但在相对的Babel页面上没有列出任何警告。)

谢谢。

2 个答案:

答案 0 :(得分:1)

我认为这很自然。如果您希望覆盖父类的属性init值,则应该在派生类的构造函数中执行此操作。

class Two extends One {

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

}

希望它有所帮助。快乐的编码(:

答案 1 :(得分:0)

loganfsmyth在这里非常清楚地回答了我的问题:https://phabricator.babeljs.io/T7567(谢谢!)

  

这确实是预期的行为。 Babel的实现有点不正确,因为在完美的世界中,这也会引发错误,因为你不应该在父母和孩子中定义相同的属性,但是我们现在不这样做。

     

在以下情况下初始化类属性:

     
      
  • 对于基类,在构造函数执行之前

  •   
  • 对于子课程,在super()

  • 的末尾   
     

当给定的构造函数初始化它的绑定时,它使用那些类绑定,它不知道子类中的任何内容。这意味着你的One类知道值应为1,这就是它所设置的内容。