Build Your Own AJAX Web Applications Part 3/3
By SitePoint Books | Published  12/7/2006 | Tutorials | Unrated
Page 3

Instead of our greeting message, the alert box that results from this version of the code will read "undefined." Because we called onTimeout with setTimeout, onTimeout is run within a new execution context. In that execution context, this no longer refers to an instance of ScopeTest, so this.message has no meaning.

The simplest way to deal with this problem of loss of scope is by making the Monitor class a special kind of class, called a singleton.

Singletons with JavaScript

A "singleton" is called that because only a "single" instance of that class exists at any time. Making a class into a singleton is surprisingly easy:

var ScopeTest = new function() {
this.message = "Greetings from ScopeTest!";
this.doTest = function() {
var onTimeout = function() {
alert(this.message);
};
setTimeout(onTimeout, 1000);
};
}

Using the keyword new before function creates a "one-shot" constructor. It creates a single instance of ScopeTest, and it's done: you can't use it to create any more ScopeTest objects.

To call the doTest method of this singleton object, you must use the actual name of the class (since there's only the one instance of it):

ScopeTest.doTest();

That's all well and good, but we haven't solved our loss of scope problem. If you were to try the code now, you'd get the same "undefined" message you saw before, because this doesn't refer to an instance of ScopeTest. However, using a singleton gives us an easy way to fix the problem. All we have to do is use the actual name of the object -- instead of the keyword this -- inside onTimeout:

var ScopeTest = new function() {
this.message = "Greetings from ScopeTest!";
this.doTest = function() {
var onTimeout = function() {
alert(ScopeTest.message);
};
setTimeout(onTimeout, 1000);
};
}

There's only one instance of ScopeTest, and we're using its actual name instead of this, so there's no confusion about which instance of ScopeTest is being referred to here.

When you execute this code, you'll see the expected value of "Greetings from ScopeTest!" in the JavaScript alert box.

Now, I get tired of using the actual object name throughout my object code, and I like to use a shortcut keyword like this wherever I possibly can. So, usually I create a variable self that I can use in place of this, and point it to the object name at the top of each method, like so:

var onTimeout = function() {
var self = ScopeTest;
alert(self.message);
};

This looks a bit silly in a method that's as short as that, but in longer chunks of code it's nice to have a shorthand solution similar to this that you can use to refer to your object. I use self, but you could use me, or heyYou, or darthVader if you wanted to.

Creating the Monitor Object

Now that we have a plan for code organization that will fix the loss-of-scope problem from setTimeout, it's time to create our base Monitor class:

Example 3.2. appmonitor2.js (excerpt)

var Monitor = new function(){
this.targetURL = null;
this.pollInterval = null;
this.maxPollEntries = null;
this.timeoutThreshold = null;
this.ajax = new Ajax();
this.start = 0;
this.pollArray = [];
this.pollHand = null;
this.timeoutHand = null;
this.reqStatus = Status;
}


Share and Enjoy:

StumbleUpon Toolbar


Article Series
This article is part 3 of a 3 part series. Other articles in this series are shown below:
  1. Build Your Own AJAX Web Applications Part 1/3
  2. Build Your Own AJAX Web Applications Part 2/3
  3. Build Your Own AJAX Web Applications Part 3/3
Comments