Child class 成员初始值设定项覆盖 parent class 构造函数

Child class member initializer overriding parent class constructor

如果我有一个应该能够在新实例上设置一些初始属性的超级 class,为什么 child class 的成员似乎会覆盖超级 class?

的构造函数

class Base {
  constructor(fields) {
    Object.assign(this, fields)
  }
}

class Foo extends Base {
  time = 0;
  
  // calling super seems to make no difference
  // constructor(...args) {
  //  super(...args)
  // }
}

const foo = new Foo({ time: 22 })

console.log(foo.time) // is 0, should be 22?

如果我从 child class 中删除 time = 0; 它会按预期工作,但我的 linter 会中断。

如何保留成员初始值设定项,即 child class 中的 time = 0;,但让超级 class 能够在其构造函数中设置属性?

只有在 super 调用完成后才能访问实例。没有class字段,看错误:

class Base {
  constructor(fields) {
    Object.assign(this, fields)
  }
}

class Foo extends Base {
  constructor(...args) {
    this.time = 0;
    super(...args)
  }
}

const foo = new Foo({ time: 22 })

Must call super constructor in derived class before accessing 'this' or returning from derived constructor

Class 字段遵循相同的逻辑,仅在超级调用完成后才分配给实例。所以

class Foo extends Base {
  time = 0;
  
  constructor(...args) {
    super(...args)

相当于

class Foo extends Base {
  constructor(...args) {
    super(...args)
    this.time = 0;

换句话说 - 在子class的构造函数(或class字段)内分配的属性被设计以覆盖在子class中分配的属性超级class构造函数。

but have the super class be able to set properties in its constructor?

一种方法是将 time 属性 的默认值设置为 0,然后传递并使用它而不是 class 字段:

class Base {
  constructor(fields) {
    Object.assign(this, fields)
  }
}

class Foo extends Base {
  constructor({ time = 0, ...rest }) {
    super({ time, ...rest })
  }
}

const foo = new Foo({ time: 22 })

console.log(foo.time)