rogermushroom
rogermushroom

Reputation: 5586

Why isn't this referring to window when called in setTimeout

If there is no binding of functions to instances in javascript how does getName() return john

function Person() {
    this.name = "john";
    this.getName = function() {
        return this.name;
    };
}

var me = new Person();
setTimeout(function(){alert(me.getName())}, 3000);

I though this would refer to the window at the point of call from setTimeout.

See jsFiddle: http://jsfiddle.net/qZeXG/

Upvotes: 1

Views: 85

Answers (2)

Wayne
Wayne

Reputation: 60414

What's happening here is that the anonymous function executed by setTimeout closes over the me variable, which is a Person instance. Because of closure, you can still reference me when that function is later called.

When you invoke me.getName() you're invoking a method on the Person instance, which sets the value of this to me inside that function. This is just a normal method invocation.

Note that in the following code:

var me = new Person();
setTimeout(function() {
    alert(this);
    alert(me.getName());
}, 3000);

...the value of this in the first alert is the window object. It's the ordinary method invocation that is changing the value.

Consider this final example:

var me = new Person();
var getName = me.getName;
setTimeout(function(){ alert(getName()) }, 3000);

In this case the function also closes over a reference to getName, but the function that that variable points to is invoked without any information about the Person instance it came from. Therefore, the value of this inside getName will be the window object.

Conclusion? This statement:

...there is no binding of functions to instances in javascript...

...is a false assumption.

Upvotes: 1

James M
James M

Reputation: 16718

this will be the Person instance, because you called getName on the me object.

If you just called getName directly and not as a property of me, this would refer to the window.

For example:

var getName = me.getName;
alert (getName ())

or

alert (me.getName.call (this))

Upvotes: 0

Related Questions