0

I need to create a class, but later add a method to the class, and that method needs access to properties of the class. I've tried binding this, but it is undefined when the method runs.

class TestClass {
  constructor(callback) {
    this.name = "Test";
    this.doSomething = callback.bind(this); // WHY DOESN'T THIS WORK?
  }
}

const TestInstance = new TestClass(
  () => {
    console.log(`${this.name} is doing something!`);
  },
);

TestInstance.doSomething(); // this is undefined

Am I doing it wrong or is this not possible?

I'm aware I could create a new class that extends the first, and call super in the constructor to access the parent's this, but for other reasons I'd prefer not to create child classes.

  • "*WHY DOESN'T THIS WORK?*" because [`.bind()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) *returns a new function*. But you don't do anything with it, so it gets discarded. – VLAZ May 10 '22 at 08:34
  • Also, related: [How to access the correct `this` inside a callback](https://stackoverflow.com/q/20279484) – VLAZ May 10 '22 at 08:35
  • I've read the related post but this is not a callback I've also tried this.doSomething = type.doSomething.bind(this) – Ron Douglas May 10 '22 at 08:38
  • 1
    Almost.. it's `this.doSomething = this.doSomething.bind(this)` – slebetman May 10 '22 at 08:41
  • @slebetman still undefined. Tried to simplify further based on vlaz's comment – Ron Douglas May 10 '22 at 08:45
  • 1
    @slebetman OP isn't trying to bind an *existing* `doSomething`, they're trying to bind `callback`. – deceze May 10 '22 at 08:45
  • 2
    The problem is that you can't bind `this` of an *arrow function*. They're explicitly *not re-bindable*. Pass a `function () { .. }` instead of an arrow function. In this case, you don't even need to `bind` at all, just assign to `this.doSomething`, and `this` will get set when calling `TestInstance.doSomething()`. – deceze May 10 '22 at 08:47
  • 1
    @deceze That's not the original question. In the original question the OP passed an object that has a member that is the function to be overridden, not a callback. I was commenting on the original question, not this completely different edited question – slebetman May 10 '22 at 08:50
  • 1
    Almost.. it's `const TestInstance = new TestClass(function () {console.log(this.name)})`. You cannot use arrow function because arrow functions are not re-bindable – slebetman May 10 '22 at 08:51
  • ah yes the arrow function is what did me in thanks all. I'd gone with the arrow function thinking it could avoid having to bind in the first place lol – Ron Douglas May 10 '22 at 08:55

0 Answers0