Tony Stark
Tony Stark

Reputation: 21

Execution context of setTimeout (JavaScript)

1) Can someone illustrate how setTimeout works in terms of execution threads.

Consider:

function foo() { alert('foo'); }
function bar() { alert('bar'); }  
setTimeout(foo,1000);
bar();

or

function foo() { alert('foo'); setTimeout(foo,1000); }
function bar() { alert('bar'); }  
setTimeout(foo,1000);
bar();

or

function foo() { alert('foo'); setTimeout(foo,1000); }
function bar() { /* an execution that runs with unknown time */ }  
setTimeout(foo,1000);
bar();

or

function foo() { alert('foo'); setTimeout(foo,1000); }
function bar() { /* some ajax call that reply with unknown time */ }  
setTimeout(foo,1000);
bar();

or

function foo() { alert('foo'); setTimeout(foo,1000); }
function bar() { alert('foo'); setTimeout(bar,1000); }  
setTimeout(foo,1000);
setTimeout(bar,1000);

2) Can someone explain how why "this" object doesn't work in setTimeout and what we can do to get around that problem?

Upvotes: 2

Views: 4425

Answers (2)

Stefan
Stefan

Reputation: 4206

Do read the article suggested by @DaveAnderson.

As to the other stuff, the setTimeout/setInterval has two forms:

setTimeout(arg, timeout)

If arg is a string, then it's treated as the source code to be executed. This is as bad as eval(). Avoid it.

If arg is a function, then it's executed in the global context:

var Test = function () {
    this.x = 1;
    setTimeout(function () {
        console.log('x: ' + this.x);
    }, 10);
};

var t = new Test();

Prints x: undefined.

So what you wanted to do is:

function foo() { alert('foo'); }
setTimeout('foo()', 1000);

or better:

setTimeout(foo, 1000);

To fix the context of the function, use the bind method:

var Test = function () {
    this.x = 1;
    var f = function () {
        console.log('x: ' + this.x);
    };
    setTimeout(f.bind(this), 10);         // use this as the context
};

var t = new Test();

or do it manually:

var Test = function () {
    this.x = 1;
    var that = this;
    setTimeout(function () {
        console.log('x: ' + that.x);     // closure: closing over that
    }, 10);
};

var t = new Test();

Upvotes: 9

Stepan Yakovenko
Stepan Yakovenko

Reputation: 9206

As far as I could recall:

var me = this;
me.f();

(this may change its meaning in another context).

Upvotes: 0

Related Questions