Javascript:在父级

时间:2019-07-19 16:36:27

标签: javascript oop inheritance babel

我在我的应用程序中使用一个父类来为其子级提供一些基本功能。大致如下:

class Base {
  constructor(stream) {
    stream.subscribe(this.onData)
  }

  onData(data) {
    throw new Error('"onData" method must be implemented')
  }
}

class Child extends Base {
  onData(data) {
    // do stuff...
  }
}

那很好,当我实例化Child时,BaseChild.onData传递给stream 唯一的问题是范围。在Child.onData中,我大量使用this关键字在child中定义的其他方法。因此,当我将此函数作为回调传递给stream时,一切都会中断。显而易见的解决方案是:

class Base {
 constructor(stream) {
   stream.subscribe(this.onData)
 }

 onData = (data) => {
   throw new Error('"onData" method must be implemented')
 }
}

class Child extends Base {
 onData = (data) => {
   // do stuff...
 }
}

那确实解决了范围问题,但是现在传递给stream的函数始终是Base.onData,这会引发错误。通常,我可以做类似将Child.onData传递给Base构造函数的事情。那会行得通,但是我想找到的是一个更优雅的解决方案,如果存在的话

1 个答案:

答案 0 :(得分:0)

这就是arrow functions in class properties are not that great的原因。如果将其翻译为普通的ES6类,则会发生以下情况:

class Child extends Base {
  constructor(...args) {
    super(...args);
    this.onData = (data) => {
      // do stuff...
    };
  }
}

现在很明显为什么无法在Base构造函数中使用该属性。

相反,您应该使用常规方法定义并通过将方法绑定到父构造函数中来处理context problem

class Base {
  constructor(stream) {
    if (this.onData == Base.prototype.onData)
      throw new Error('"onData" method must be overridden')
    this.onData = this.onData.bind(this);
    stream.subscribe(this.onData)
  }

  onData(data) {}
}

class Child extends Base {
  onData(data) {
    // do stuff...
  }
}