apss1943
apss1943

Reputation: 269

'this' concept in the object in javascript

I am sorry for that the simple question first. But I just want to know what happen in the code below.

var indexobj = {
    test : 1,
    testFunction : function() {
        document.getElementById('AA').innerHTML = indexobj.test++;
        //this is i wanted
        document.getElementById('BB').innerHTML = this.test++;
        //NaN
        setTimeout(indexobj.testFunction,1000);
    },
}
setTimeout(indexobj.testFunction,1);

Here is the sample link below

http://jsfiddle.net/apss/JR5Xk/28/

Why in this example the ‘this’ inside the ‘testFunction’ function doesn’t mean ‘indexobj’ this object? Thanks for your help.

Upvotes: 4

Views: 226

Answers (2)

dfsq
dfsq

Reputation: 193301

Because setTimeout runs callback function in global object context, meaning that indexobj.testFunction is invoked with this being a window object.

So you can either do

setTimeout(function() {
    indexobj.testFunction();
},1000);

or using Function.prototype.bind to create wrapper function with correct context:

setTimeout(indexobj.testFunction.bind(indexobj), 1000);

Another modern option from ES2015 is to use arrow function that preserves lexical context:

setTimeout(() => indexobj.testFunction(), 1000);

Upvotes: 6

RobG
RobG

Reputation: 147513

A function's this set set by:

  1. How the function is called

  2. the use of bind.

I doesn't matter where it's called from.

In this case, you have:

setTimeout(indexobj.testFunction,1000);

which passes the function referenced by indexobj.testFunction to be called later by setTimeout. When called, the function is called directly, so its this isn't set by the call and it defaults to the global object (window in a browser) or remains undefined in strict mode.

You can fix that in a number of ways, one is to pass a function that sets indexobj to this in the call:

setTimeout(function(){indexobj.testFunction()}, 1000);

or you can use bind as suggested by dfsq.

Arrow functions in the ES6 draft change how this is set, but that's for the next edition…

Upvotes: 3

Related Questions