setTimeout() in Objects

Quite a few years ago, I ran into a problem with using setTimeout() where I wanted to repeatedly call an object’s method inside of that method. For example:

MyObj.prototype.Foo = function (arg1) {
if (arg1 < 5) {
arg1++;
setTimeout(“this.Foo()”, 100);
} else alert("Done");
};

Of course, this never worked since JavaScript was actually trying to find a this object (which doesn’t exist) to run the Foo() method. My early solution was to use a global variable:

setTimeout("GlobalVar[\""+UniqueIdentifier+"\"].Foo("+arg1+")", 100);

While this approach works, it does not fit into an object oriented style of coding. Instead of everything being encapsulated within the class and/or method, the class/method is totally dependant upon a global variable... which is unacceptable to me nowdays.

I am writing a script for Foo that requires a setTimeout(), so naturally I wanted to find a new way of doing this. Since it has been a few months since I read it, I opened up the newly published Professional JavaScript for Web Developers and headed to the setTimeout() section hoping to find some insight… and I found some. It seems that I had forgotten that you can use a function pointer in setTimeout() instead of a string:

setTimeout(fpFuncName, 100);

Now we’re getting somewhere. I make a few changes to my method and hit Ctrl+F5:

MyObj.prototype.Foo = function (arg1) {
if (arg1 < 5) {
arg1++;
var myFunc = function () {
this.Foo(arg1);
};
setTimeout(myFunc, 100);
} else alert("Done");
};

Doh! Still getting errors saying this.Foo is not a function. So I remember a scope-based trick I learned a while back where I assign the object (this) to a variable and use the variable in place of this:

……
arg1++;
var thisObj = this;
var myFunc = function () {
thisObj.Foo(arg1);
};
setTimeout(myFunc, 100);
……

Viola! It works! Now I have everything I need nicely encapsulated within the method, and the class doesn’t rely upon any external variables or objects.

4/23/2005 12:00:00 AM | Tags: JavaScript
© 2008 Jeremy McPeak