0

I have:

function MyFunc() {
  this.myString = "wooooo";
  setTimeout(function () {
    console.log("printing this.myString", this.myString);
  }, 1000);
}

MyFunc();

If I run this inside node, I get the answer: printing this.myString undefined (btw node --version gives v12.16.2)

If I try this inside my console devtools in chrome browser, I get printing this.myString wooooo (btw I have chrome 89.0.4389.90)

Can anybody explain me why this is different in nodejs and js? Why has it different behaviour?

Thank you

holyduke
  • 13
  • 4
  • This also happens in `node 15.5.1`. I don't think this is a V8 issue since both node and chrome use the v8 engine – evolutionxbox Mar 21 '21 at 19:51
  • Looks like this is because `this` inside the timeout handler refers to an instance of https://nodejs.org/api/timers.html#timers_class_timeout . I couldn't find anything in the spec about what `this` is supposed to refer to in the timeout handler, so my guess is that the host environment decides. Browsers don't set a specific `this` value and Node seems to set the mentioned value. – Felix Kling Mar 21 '21 at 20:04
  • I was actually trying this tutorial: https://www.youtube.com/watch?v=gigtS_5KOqo&t=335s – holyduke Mar 21 '21 at 20:06

1 Answers1

1

At first glance, both references to this should refer to the global object (assuming non-strict mode), since both references occur in "normal" functions.

That's what happens in the browser.

However, if you actually log the value of this you can see that it refers to an instance of Timeout in Node:

Timeout {
  _idleTimeout: 1000,
  _idlePrev: null,
  _idleNext: null,
  _idleStart: 21,
  _onTimeout: [Function (anonymous)],
  _timerArgs: undefined,
  _repeat: null,
  _destroyed: false,
  [Symbol(refed)]: true,
  [Symbol(kHasPrimitive)]: false,
  [Symbol(asyncId)]: 5,
  [Symbol(triggerId)]: 1
}

It's very possible that it's not officially defined what this is supposed to refer to in the handler, so environments are free to do whatever they want in this regard.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • It seems to be defined as `window` here: https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timer-initialisation-steps. Although nobody says node should follow a DOM standard. – georg Mar 21 '21 at 20:22
  • @georg: Ah and step 7.2 also says: *"Use method context proxy as the callback this value."*... I was looking for the wrong keywords. But yeah, I guess Node just provides a `setTimeout` implementation for convenience, not for following the DOM spec. – Felix Kling Mar 22 '21 at 12:51