Tuesday, February 12, 2013

setInterval/setTimeout and this

I think everybody is familiar with the setInterval and the setTimeout functions. They create a timed event which will occur after a given timeout. setInterval creates an interval: after the given time it will repeat the same action over and over, while the setTimeout function will only execute the action once. Let's see a small example on how they work:

var timed_function = function(){
    console.log("hello!");
}

var timeout = setInterval(timed_function, 1000);


The shown example will execute every second (1000 milliseconds) the function timed_function.

Now, I recently worked with a timed event and I had to access a variable within this. The naive approach was the following:


//previously set variable
this.message = "hello!";

var timed_function = function(){
    console.log(this.message);
}

var timeout = setInterval(timed_function, 1000);

But this printed undefined. I then discovered that when setInterval or setTimeout are executed, the scope of this apparently refers to the window object, thus it's completely loosing the scope of the object in which the function is executed. The idea to solve this problem is to wrap the call inside another object which has to be called to initialise the timeout:


//previously set variable
this.message = "hello!";

var wrapper = function(that) {
    var timed_function = function(){
        console.log(that.message);
    }

    var timeout = setInterval(timed_function, 1000);
}

//later
wrapper(this);

In this way I basically instantiate the timeout passing through the wrapper function which will keep a reference to this thanks to the input variable of the function. The input variable then will be called inside the timed_function. Hope this helped somebody. I had a couple of issues trying to solve this because I was confused by the scope of the variables. Some folks helped me on StackOverflow luckily, even though some of them where short-sighted and arrogant as always.
Categories: ,

0 comments:

Post a Comment