[removed] overriden methods defined as arrow funct

2019-09-19 12:17发布

I am using a parent class in my app to provide some basic functionality to its children. It looks roughly like this:

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...
  }
}

That works fine and when I instantiate the Child, Base passes Child.onData to the stream The only problem is scope. In Child.onData I make a heavy use of other methods defined in child via this keyword. So when I pass this function as a callback to the stream, everything breaks. The evident solution is this:

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...
 }
}

That does solve problems with scope, but now the function that is being passed to the stream is always Base.onData which throws errors. Generally, I could do something like passing the Child.onData to Base constructor. That would work, but what I would like to find is a more elegant solution to this, if it exists

1条回答
Evening l夕情丶
2楼-- · 2019-09-19 12:39

That's why arrow functions in class properties are not that great. If you translate it to a normal ES6 class, this is what happens:

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

It's rather evident now why using the property inside the Base constructor doesn't work.

Instead, you should use normal method definitions and handle the context problem by binding the method inside the parent constructor:

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...
  }
}
查看更多
登录 后发表回答