Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a javascript method loose connection with the object when used with setTimeout

The code below prints out:

timedout false undefined

I.e. this is no longer refering to theActivityTimer in method timedOut(). I was wondering why this was.

var theActivityTimer = {
    timer: "",          
    active: false,       

    refresh: function () {
        theActivityTimer.timer = setTimeout(
            this.timedOut,
            5000     
        );
    },

    timedOut: function(){
        alert("timedout " +
            theActivityTimer.active + " " + this.active);
    }
}

theActivityTimer.refresh();

http://jsfiddle.net/spiderplant0/nQ4XX/

And is there a way to tell get it to work with this

like image 211
spiderplant0 Avatar asked Jan 26 '26 22:01

spiderplant0


1 Answers

this is based on how the method is invoked.

foo.bar(); // this === foo

var bar = foo.bar();
bar() // this === window (defaults to global object)

So setTimeout effectively does the latter.

Instead, it's common to pass an anonymous function that maintains the proper call to your instance method. Just remember that the anonymous function will also lose this, so you need to save what this is to a local variable, which is also common.

var self = this;
theActivityTimer.timer = setTimeout(function() {
    self.timedOut()
}, 5000);

There are other ways to manipulate context (the value of this), but this one is probably the easiest to understand and the most widely supported.

like image 91
Alex Wayne Avatar answered Jan 29 '26 13:01

Alex Wayne