Using Custom Objects in JavaScript
January 12, 2010Objects 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | // 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 += " "; htmlOutput += "<span>Title: " + album.title + "</span> "; htmlOutput += "<span>Artist: " + album.artist() + "</span> "; htmlOutput += "<span>Label: " + album.label + "</span> "; htmlOutput += "<span>Year: " + album.year + "</span> "; htmlOutput += " "; // Loop through the tracks: for (var i = 0; i < album.tracks.length; i++) { htmlOutput += " "; htmlOutput += "<span>Track " + (i+1) + ":</span> "; htmlOutput += "<span>Title: " + album.tracks[i].title + "</span> "; htmlOutput += "<span>Composer: " + album.tracks[i].composer() + "</span> "; htmlOutput += "<span>Time: " + album.tracks[i].time + "</span> "; // 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> "; } // End personnel loop. htmlOutput += " "; } // 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:
1 | 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:
1 | 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:
1 | 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:
1 | 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.
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
1 | <script src="albuminfo.js" type="text/javascript"></script> |
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.




