In the following code, I would expect printHello to be called twice (once from go() and once from runTask()):
class Hello {
  task = undefined;
  runTask() {
    console.log("Task is", this.task);
    this.task();
  }
  
  printHello() { 
    console.log("Hello"); 
  }
  
  go() {
    this.task = this.printHello;
    console.log("Set task to", this.task);
    setTimeout(this.runTask, 0); // Fails
    // setTimeout(() => this.runTask(), 0); // Works
  }
};
const hello = new Hello();
hello.go(); // Says `this.task` is undefined, but then...
hello.runTask(); // ... running it manually works fine
In my mind:
- I create an instance of the class
- Then calling go()- Sets the taskfield/property on that instance toprintHello
- Sets up a request to runTaskafter the timeout
 
- Sets the 
I would expect that runTask would be called with task set to printHello, but it's actually undefined in the setTimeout call. However, if I just call runTask directly on my hello instance it works fine. Also, if I replace the setTimeout call with a lambda it works fine.
It seems clear it's a stale closure type of issue, I just don't have a great mental model or rulebook that would prevent me from writing code like this in the future and then be perplexed about why it wasn't working.
I was thinking that this would be captured when passing runTask, which should then point to a valid task, but that's not the case.
I'd really appreciate some insight about exactly why this doesn't work and requires the lambda version to be used.
