logo

March 26th, 2007

If you’d like to use setTimeout() or setInterval() methods for specific object methods, you can do so by using a function closure in the following manner:

function Foo(bar)
{
this.bar = bar;
this.alertBar = function () {
alert(this.bar);
};
this.alertBarTimeout = function (ms){
var _self = this;
setTimeout(function(ms){
_self.alertBar();
}, ms);
};
}
foo = new Foo("show me");
foo.alertBarTimeout(1000);

Function closures are documented all over the web, but here is a quick overview:

Javascript is a dynamic language, and one of the properties of a dynamic language is the ability to add properties and methods at runtime. A function closure is a special property of a function definition in which local variables from the definers scope are available in the scope of the definee.

For example, in the body of Foo.alertBarTimeout() the variable _self is defined, and set to be a reference of this instance. This is important because in order to have setTimeout() work on this instance, it needs to know about it explicitly.

this.alertBarTimeout = function (ms){
var _self = this;
setTimeout(function(ms){
_self.alertBar();
}, ms);
};

Because we are passing a function into setTimeout that is defined within Foo.alertBarTimeout(), the local variable _self is available in both Foo.alertBarTimeout() and the function passed into setTimeout().

this.alertBarTimeout = function (ms){
var _self = this;
setTimeout(function(ms){
_self.alertBar();
}, ms);
};

Therefore, when _self.alertBar() is executed _self retains its scoped value and alertBar() will execute on this instance of Foo.

this.alertBarTimeout = function (ms){
var _self = this;
setTimeout(function(ms{
_self.alertBar();)
}, ms);
};

The result is as expected. In this case, an alert will pop up with “show me” 1000ms (1 second) after the call to alertBarTimeout() is made.