分类: 系统运维
2007-11-05 21:29:24
The CO2Levels
object definition appears in a different JavaScript file, aptly named co2.js. Figure 1-2 shows a UML class diagram describing the object.
Figure 1-2. UML class diagram
Here is the entire code for the CO2Levels
object. The first line instantiates a new object, using syntax derived from Prototype. The levels
local variable is an object, like an associative array, that links
years with their CO2 levels. I have omitted most of the years for the
sake of readability.
var CO2Levels=Class.create();
CO2Levels.prototype = {
/*
Source:
Mauna Loa Observatory, Hawaii
*/
initialize: function(){
this.levels={ "1959":315.98,"1960":316.91,
"1961":317.65,"1962":318.45,
"2003":375.64,"2004":377.38};
this.levelsHash=$H(this.levels);
},
getYear: function(year){
if (! isNaN(year)) {
return this.levelsHash[year];
} else {
return 377;
}
},
keys: function(){
return this.levelsHash.keys();
},
values: function(){
return this.levelsHash.values();
},
inspect: function(){
alert( this.levelsHash.inspect());
},
add: function(year,level){
var tmp = new Object();
tmp[year] = level;
this.levelsHash=this.levelsHash.merge(tmp);
}
}
Using the Class.create()
method in Prototype returns a JavaScript object that automatically provides new instances of this object with an initialize()
method. This is similar to a constructor method, such as in Java. The initialize()
method will be called each time the code creates a new CO2Levels
object. The rest of the code defines the prototype, or blueprint, for this CO2Levels
object, including the behavior for its initialize()
method. What does initialize()
do? It creates a local variable called levels
,
which refers to an object that holds all of the data: the CO2 levels
associated with their years. The code then converts this object to a
Prototype Hash
object, to provide more functionality for
the object (such as the ability to view the object contents and
dynamically add new data).
this.levelsHash=$H(this.levels);
Hash
ObjectThere's that syntax again: $H()
. This function takes a JavaScript object as its parameter and returns Prototype's Hash
object. Similar to hash table structures in other languages, the Hash
has an associative array structure, along with with several methods
that are designed to manipulate its data, as well as add new data to
the Hash
.
For example, the Hash.keys()
method returns an array of all of the Hash
's keys (such as all of the years in our data). The values()
method returns an array of values (the CO2 levels). The merge()
method adds new keys and values to the Hash
.
Our own CO2Levels
object uses the concept of delegation, wherein calls to its own keys()
, values()
, and add()
methods delegate the real work of these operations to the internal Hash
object. This object is stored as a local variable: levelsHash.
Let's look at the getYear()
method.
getYear: function(year){
if (! isNaN(year)) {
return this.levelsHash[year];
} else {
return 377;
}
}
The built-in JavaScript method isNaN()
returns false if its parameter can be evaluated as a number (such as "2000"
), and true otherwise (as in isNaN("hello")
). If the getYear()
parameter passes this test, then the code uses a common JavaScript expression to return the value of a key or property: this.levelsHash[year]
(for example, this.levelsHash["2004"]
evaluates to 377.38). The browser then displays this numerical value inside the HTML div
element.
The CO2Levels
object has an add()
method, which can add new keys and values (additional years and CO2 levels) to the existing data.
add: function(year,level){
var tmp = new Object();
tmp[year] = level;
this.levelsHash=this.levelsHash.merge(tmp);
}
This method creates a new Object
from its two parameters (representing the year and CO2 level), which might look like: {"2005":381}
The code then passes this object to the Prototype Hash
object's merge()
method. This method combines the new object with the Hash
's existing data, essentially merging them into one group of data or associative array.
The merge()
method returns the existing data with the new property/value pair(s) appended to the end.
With some refactoring, the code could use XMLHttpRequest
to fetch any new levels from the Mauna Loa Observatory, then add them to our existing client-side data.
Finally, Prototype's Hash
object also has an inspect()
method. This method creates a readable display of the Hash
's contents, as in Figure 1-3.
Figure 1-3. Looking inside a Hash
The CO2Levels
object delegates the task of its own inspect()
method to its internal Prototype Hash
object.
inspect: function(){
alert( this.levelsHash.inspect());
}
This is a useful debugging tool for viewing the current contents of a Hash
object.
An upcoming article discusses an AJAX caching strategy used with the same application. It introduces Prototype's Ajax.Request
object, which reduces the amount of code that has to be devoted to using the XMLHttpRequest
object. This is the important top-level JavaScript object used in AJAX
applications for making HTTP connections with a server behind the
scenes.