setTimeout and setInterval

Usage

These function are simple enough to understand — pass it a function, and a duration. After the duration has elapsed the passed function will be called once (if using setTimeout) or repeatedly (if using setInterval). Example:

var blinkInterval = window.setInterval(blink, 2000); //calls blink every two seconds

function blink() {
	//flash a light
}

function killBlinky() {
	window.clearInterval(blinkInterval);
}

It is possible to cancel the blinking by calling clearInterval.

Very frequently you will find that you want to pass a parameter or context to the called function; now it gets interesting. Read on...

Passing Context

Old School Method—Use a Closure

Mozilla describes this well. Basically, when these timer functions call your custom function, the context is set at the document root level. In the example below, self was created so that a closure would be created around it when the anonymous function inside setInterval is declared. If you tried to reference the Person methods directly (e.g. this.incrementReminder(); ) then you would get the error message “this.incrementReminder is not a function” because this refers to the window object, not a Person instance.

var Person = function(fullName) {
	this.fullName = fullName;
	this.reminders = 0; 
}
Person.prototype.incrementReminder = function() {
	this.reminders++;
}
Person.prototype.toString = function() {
	return this.fullName + ' has been reminded ' + this.reminders + ' times.';
}
Person.prototype.beginReminders = function(seconds) {
	var self = this;
	window.setInterval(function() {
		// BAD CODE => this.incrementReminder();
		self.incrementReminder();
		console.log(String(self));
	}, seconds * 1000);
}

var craig = new Person("Craig Stronbolli");
var nancy = new Person("Nancy Lopez");

console.log(String(craig));
console.log(String(nancy));

craig.beginReminders(2);
nancy.beginReminders(5);

Binding Context Method

Using Function.prototype.bind() is a rather elegent way to handle the problem. Using the example above, replace Person.prototype.beginReminders with this:

Person.prototype.beginReminders = function(seconds) {
	window.setInterval((function() {
		this.incrementReminder();
		console.log(String(this));
	}).bind(this), seconds * 1000);
};

New School Method—ES6 Arrow Functions

If you are using ES6 syntax, then use:

Person.prototype.beginReminders = function(seconds) {
	window.setInterval(() => {
		this.incrementReminder();
		console.log(String(this));
	}, seconds * 1000);
};