Objects provide a simple, powerful way to store and manipulate data, and should be part of every JavaScript developer’s toolkit. This short tutorial will demonstrate how to create custom objects for your data.
Note: This is not an in-depth tutorial. You should already be comfortable with basic JavaScript and programming concepts like functions and arrays before you start.
Start by examining the code in example 1:
Example 1: albuminfo.js
// Object definitions:
function albumObject(theTitle, theArtistFirstName, theArtistLastName, theLabel, releaseYear, tracksArray) {
this.title = theTitle;
this.artistFirstName = theArtistFirstName;
this.artistLastName = theArtistLastName;
this.label = theLabel;
this.year = releaseYear;
this.tracks = tracksArray;
this.artist = function() {
return this.artistFirstName + " " + this.artistLastName;
}
}
function trackObject(theTitle, theComposerFirstName, theComposerLastName, trackLength, personnelArray) {
this.title = theTitle;
this.composerFirstName = theComposerFirstName;
this.composerLastName = theComposerLastName;
this.time = trackLength;
this.personnel = personnelArray;
this.composer = function() {
return this.composerFirstName + " " + this.composerLastName;
}
}
function personnelObject(theFirstName, theLastName, theInstrument) {
this.firstName = theFirstName;
this.lastName = theLastName;
this.instrument = theInstrument;
this.credit = function() {
return this.firstName + " " + this.lastName + " - " + this.instrument;
}
}
// Function definitions:
function albumPersonnel() {
var allPersonnel = new Array();
allPersonnel['Davis'] = new personnelObject(
"Miles",
"Davis",
"Trumpet");
allPersonnel["Shorter"] = new personnelObject(
"Wayne",
"Shoter",
"Tenor Saxophone");
allPersonnel["Hancock"] = new personnelObject(
"Herbie",
"Hancock",
"Piano & Electric Piano");
allPersonnel["Corea"] = new personnelObject(
"Chick",
"Corea",
"Electric Piano");
allPersonnel["Carter"] = new personnelObject(
"Ron",
"Carter",
"Bass");
allPersonnel["Holland"] = new personnelObject(
"Dave",
"Holland",
"Bass");
allPersonnel["Williams"] = new personnelObject(
"Tony",
"Williams",
"Drums");
return allPersonnel;
}
function personnelSideA() {
allPersonnel = albumPersonnel();
personnel = new Array();
personnel[0] = allPersonnel["Davis"];
personnel[1] = allPersonnel["Shorter"];
personnel[2] = allPersonnel["Hancock"];
personnel[3] = allPersonnel["Carter"];
personnel[4] = allPersonnel["Williams"];
return personnel;
}
function personnelSideB() {
allPersonnel = albumPersonnel();
personnel = new Array();
personnel[0] = allPersonnel["Davis"];
personnel[1] = allPersonnel["Shorter"];
personnel[2] = allPersonnel["Hancock"];
personnel[3] = allPersonnel["Corea"];
personnel[4] = allPersonnel["Holland"];
personnel[5] = allPersonnel["Williams"];
return personnel;
}
function trackList() {
personnelA = personnelSideA();
personnelB = personnelSideB();
tracks = new Array();
tracks[0] = new trackObject(
"Water Babies",
"Wayne",
"Shorter",
"5:06",
personnelA);
tracks[1] = new trackObject(
"Capricorn",
"Wayne",
"Shorter",
"8:27",
personnelA);
tracks[2] = new trackObject(
"Sweet Pea",
"Wayne",
"Shorter",
"7:59",
personnelA);
tracks[3] = new trackObject(
"Two Faced",
"Wayne",
"Shorter",
"18:01",
personnelB);
tracks[4] = new trackObject(
"Dual Mr. Anthony Tillmon Williams Process",
"Miles",
"Davis",
"13:20",
personnelB);
tracks[5] = new trackObject(
"Splash",
"Miles",
"Davis",
"10:05",
personnelB);
return tracks;
}
function albumInfo() {
var album = new albumObject(
"Water Babies",
"Miles",
"Davis",
"Columbia",
"1976",
trackList());
return album;
}
function printAlbum() {
album = albumInfo();
var htmlOutput = "";
htmlOutput += "<p>";
htmlOutput += "<span>Title: " + album.title + "</span><br />";
htmlOutput += "<span>Artist: " + album.artist() + "</span><br />";
htmlOutput += "<span>Label: " + album.label + "</span><br />";
htmlOutput += "<span>Year: " + album.year + "</span><br />";
htmlOutput += "</p>";
// Loop through the tracks:
for (var i = 0; i < album.tracks.length; i++) {
htmlOutput += "<p>";
htmlOutput += "<span>Track " + (i+1) + ":</span><br />";
htmlOutput += "<span>Title: " + album.tracks[i].title + "</span><br />";
htmlOutput += "<span>Composer: " + album.tracks[i].composer() + "</span><br />";
htmlOutput += "<span>Time: " + album.tracks[i].time + "</span><br />";
// Loop through the personnel listings for the current track:
for (var n = 0; n < album.tracks[i].personnel.length; n++) {
htmlOutput += "<span>" + album.tracks[i].personnel[n].credit() + "</span><br />";
} // End personnel loop.
htmlOutput += "</p>";
} // End tracks loop.
document.write(htmlOutput); // Write the album info to the page.
} // End function printAlbum.
// Implementation:
window.onload = printAlbum; // Call the printAlbum function when the page has finished loading.
There is a lot going on here, so let’s dig deeper and see what it all does.
Explaining Object Definitions
The first three functions are object definitions. These serve as templates for the information you will store and manipulate. Object definitions look a lot like like regular functions. You pass data to the object definition the same way you would pass values to a function, then create properties to store it.
A property definition looks like this:
this.theProperty = theData;
In the above, this refers to the object itself, theProperty is the name of the property, and theData is data that was passed to the object definition. Properties can store simple values, like strings and numbers, arrays, or even other objects.
You access properties like this:
var result = theObject.theProperty;
Properties can also represent functions. This allows you to create objects that can perform complex (or not so complex) operations on their own data, and return a result. Look at the albumObject() definition in example 1. The artist property represents a function that compiles the artist’s first and last names into a single string, with a space between the names. Similar functions are used in the trackObject and personnelObject definitions to make it easier to access full names. Remember that whenever you access a property that represents a function, you have to include the brackets at the end of the function name:
var result = theObject.theFunction();
Implementation
Now that we have taken a quick overview of object definitions, let’s work backwards though the rest of the code to see how it works. The implementation line is very simple:
window.onload = printAlbum;
This calls the printAlbum function when the window has finished loading. The first line of the printAlbum function creates a variable called album to store the result of the albumInfo function.
The albumInfo function simply creates and returns a new albumObject object. Notice that the last argument passed to the new object is a call to the trackList function. The result of this function call will be stored in the tracks property.
The trackList function returns an array of trackObject objects, which contain information about the album’s tracks. The first two lines of the trackList function are calls to the personnelSideA and personnelSideB functions, which return arrays of personnelObject objects. Each instance of personnelObject contains the name and role of a different contributor. The personnelSideA and personnelSideB functions both call the allPersonnel, which creates all the personnelObject objects for the entire album.
Turning our attention back to the printAlbum function, we can summarize the album object as follows:
- 1. The album object is an instance of albumObject, and stores general information about the album.
- 2. The album object contains a property called tracks, which stores an array of trackObject objects.
- 3. Each instance of trackObject contains a property called personnel, which stores an array of personnelObject objects.
The remainder of the printAlbum function writes the contents of the album object to the document. Example 2 shows the result.
Title: Water Babies
Artist: Miles Davis
Label: Columbia
Year: 1976
Track 1:
Title: Water Babies
Composer: Wayne Shorter
Time: 5:06
Miles Davis – Trumpet
Wayne Shoter – Tenor Saxophone
Herbie Hancock – Piano & Electric Piano
Ron Carter – Bass
Tony Williams – Drums
Track 2:
Title: Capricorn
Composer: Wayne Shorter
Time: 8:27
Miles Davis – Trumpet
Wayne Shoter – Tenor Saxophone
Herbie Hancock – Piano & Electric Piano
Ron Carter – Bass
Tony Williams – Drums
Track 3:
Title: Sweet Pea
Composer: Wayne Shorter
Time: 7:59
Miles Davis – Trumpet
Wayne Shoter – Tenor Saxophone
Herbie Hancock – Piano & Electric Piano
Ron Carter – Bass
Tony Williams – Drums
Track 4:
Title: Two Faced
Composer: Wayne Shorter
Time: 18:01
Miles Davis – Trumpet
Wayne Shoter – Tenor Saxophone
Herbie Hancock – Piano & Electric Piano
Chick Corea – Electric Piano
Dave Holland – Bass
Tony Williams – Drums
Track 5:
Title: Dual Mr. Anthony Tillmon Williams Process
Composer: Miles Davis
Time: 13:20
Miles Davis – Trumpet
Wayne Shoter – Tenor Saxophone
Herbie Hancock – Piano & Electric Piano
Chick Corea – Electric Piano
Dave Holland – Bass
Tony Williams – Drums
Track 6:
Title: Splash
Composer: Miles Davis
Time: 10:05
Miles Davis – Trumpet
Wayne Shoter – Tenor Saxophone
Herbie Hancock – Piano & Electric Piano
Chick Corea – Electric Piano
Dave Holland – Bass
Tony Williams – Drums
If you want to try the script for yourself, you’ll need to reference it from an HTML document. Example 3 provides a basic one that will do the trick.
Example 3: albuminfo.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="albuminfo.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Album Info</title>
</head>
<body>
</body>
</html>
Wrapping Up
There we have it! All that data is wrapped up in one little object, easily accessible whenever we need it. The usefulness of custom objects goes beyond static data storage. For example, I use them to track users’ mouse clicks and movements when designing complex user interfaces. By creating objects to represent each element on a page, I can independently track which objects have been clicked and change their state or appearance accordingly. Custom objects can take a lot of the pain out of JavaScript programming, and make your scripts more efficient at the same time.
