我在我的应用程序中使用一个父类来为其子级提供一些基本功能。大致如下:
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
时,Base
将Child.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
构造函数的事情。那会行得通,但是我想找到的是一个更优雅的解决方案,如果存在的话
答案 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...
}
}