从父类构造函数分配时,类实例字段未定义

Con*_*tin 0 javascript oop ecmascript-6

我试图理解为什么以下解决方案在从父级构造函数分配类字段的情况下不起作用的动态:

class B{
  constructor(val){
        this.a = val;
    }
}

class A extends B{
  a;
  constructor(val){
    super(val);
  }
}
Run Code Online (Sandbox Code Playgroud)

通过上面的调用new A(1)将返回一个实例,而A.ais undefined

如果分配是通过命名function而不是超级完成, constructor 则实现将起作用

class B{
  assignMe(val){
        this.a = val;
    }
}

class A extends B{
  a;
  constructor(val){
    super(null);
    super.assignMe(val);
  }
}
Run Code Online (Sandbox Code Playgroud)

这正确设置了A.a = 1.

这里有一个更复杂的实现,它代表了我的真实使用场景。

为什么我不能通过使用来实现这一点 constructor

T.J*_*der 5

发生这种情况的原因是,通过a在 中声明属性,当的构造函数到达它可以访问的点时(就在调用 后) A,您将用新的属性替换该属性。就好像您在构造函数中编写了这段代码(挥舞着一些细节):aAthissuper()

class A extends B {
    constructor(val) {
        super(val);
        Object.defineProperty(this, "a", {
            value: undefined,
            writable: true,
            configurable: true,
            enumerable: true
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在公共领域提案中找到有关该内容([[Set]][[Define]]设计点)的详细信息。

您已经说过,在您的真实代码中,B拥有该属性a并且拥有A它。a解决方案是删除from的声明,以便它使用在构造函数中初始化的A声明:B

class B {
    a;
    constructor(val) {
        this.a = val;
    }
}

class A extends B {
    constructor(val) {
      super(val);
    }
}
Run Code Online (Sandbox Code Playgroud)