1

Was reading through MDN and came across this

function Person() {
  // The Person() constructor defines `this` as an instance of itself.
  this.age = 0;

  setInterval(function growUp() {
    // In non-strict mode, the growUp() function defines `this` 
    // as the global object, which is different from the `this`
    // defined by the Person() constructor.
    this.age++;
  }, 1000);
}

var p = new Person();

Why is it that this inside the function growUp() binds to window?

Aaron
  • 122
  • 7

2 Answers2

0

'this' in the setTimeout handler is referring to window object as the context of the Person object is gone, after which setTimeout callback function has reference to the window object.

mn.agg
  • 281
  • 1
  • 8
  • 1
    `as the context of the Person object is gone` can you elaborate on this? – Aaron May 20 '17 at 07:08
  • Execution of Person function got completed and the setTimeout callback function didn't got the reference of Person till that point.And when the actual callback function got executed this started referring to window object for that function. To resolve such scenario we save the current object i.e. 'this' in a variable and start using variable instead of 'this' – mn.agg May 20 '17 at 07:12
0

Because this is not bound to anything else. If it is not bound then it is bound when called to default object. Default is global window object.

If you need to bind it to person you can explicitly do it with bind function:

function Person() {
   this.age = 0;

  setInterval(function growUp() {
    this.age++;
  }.bind(this), 1000);
}

var p = new Person();

Edit:

In javascript you have two ways of calling function:

As function itself

function f() {}
f();

As property of the object

var obj = {
    f: function() {}
};
obj.f();

Via object prototype:

function X() {}
X.protoype.f = function() {}
var x = new X();
x.f()

For the first case this is not defined and need to be set to something. By default it is global object (window object in browser).

For the second and third case this is set to the object before dot '.' and they differs only how the function is found.

Dmitry Poroh
  • 3,705
  • 20
  • 34
  • So no matter where setInterval is called, it will always bind to `window`? without manually changing the context of course. – Aaron May 20 '17 at 07:14
  • Thanks, but I'm trying to get to the reason of why it's not bound to anything else. From what the way I see it, the `this` in Person is calling `setInterval`; which is clearly wrong. – Aaron May 20 '17 at 07:18
  • Person creates function that called by timer service. Why created function is not bound by default to the same object that creates the function... I've try to add this to answer. – Dmitry Poroh May 20 '17 at 07:22
  • Think I am understanding it now. setInterval is more like initiated by `Person` then later window calls it? which at this point the this refers to window. – Aaron May 20 '17 at 07:32
  • This more or less correct. this is really is set to object before operator '.' . When interval function is called then no such object and by default this is set to window/global object – Dmitry Poroh May 20 '17 at 07:38