Using a timer loop in a Javascript prototype

The following does not execute a loop:

function sequencer(){
    //empty for proof of concept
}
sequencer.prototype.start = function(){
    console.log("not looping");
    tid = setTimeout(this.start, 2000);
}

one = new sequencer();
one.start();

The following is a loop:

function start() {
    console.log("looping");
    tid = setTimeout(start, 2000); 
}

start();

Why does a function declared as a class method behave differently?

+3
source share
2 answers

This is because when a function is called from setTimeout, its context is set to window. It looks like this:

this.start.call(window)

So, when start()called again, thisis window, and since it window.startdoes not exist, it does not start again.

You can try this as follows:

setTimeout(this.start.bind(this), 2000);
+3
source

When called a second time, thisit is not an instance of a sequencer, it is a window object. Create a simple closure to capture this.

function sequencer(){
    //empty for proof of concept
}
sequencer.prototype.start = function(){
    var that = this;
    console.log("not looping");
    setTimeout(function(){that.start()}, 2000);
}

var one = new sequencer();
one.start();

JS Fiddle: http://jsfiddle.net/F4HgD/

+1

All Articles