« The Web designer’s guide to starting a career fresh out of college

The top ten questions every programmer should ask on a job interview »

Learn to create custom methods and properties for JavaScript objects

June 15th, 2007 by Brian | 1 Comment »

As the Web applications you develop grow larger and increasingly complex, code reuse becomes more important. You can find yourself repeating several tasks, and it becomes a necessity to understand object-oriented programming (OOP) for JavaScript. This can be a frustrating experience, since there are so many opinions on coding style. Regardless, in your research, you will undoubtedly find yourself face-to-face with a very powerful OOP concept, called prototype.

Prototype (not to be confused with the JavaScript library), has been available since JavaScript v.1.1. The objects you create in JavaScript will have a prototype member available for each property and method. When you declare a new method or property using prototype, every instance of the object containing that property or method will have access to it. If you do not use prototype, every time you initialize the object, you will have to declare the property or method again. For example:

var Water = function() {}
Water.splash = function() {
   return "Stop splashing me!";
}

We just created a constructor for a new water object, and then we gave it a method named splash(). Further into our application, we want to initialize our water object, and call the splash method. The following will throw an error:

var tapWater = new Water();
alert(tapWater.splash());

The console says our new tapWater object does not support that method. Even though tapWater uses the Water constructor, the splash method is only available to the Water object. This can be confusing at first, since our water constructor appears to be both an object and a constructor for new objects. It is, because a function in JavaScript can itself be an object! We must instead declare splash with the prototype property in order to make it available to all instances of the water object. For example:

var Water = function() {}
Water.prototype.splash = function() {
   return "Stop splashing me!";
}

Now, when we create a new instance of Water, we can splash people! How about we use our bottled water to get someone wet.

var bottledWater = new Water();
alert(bottledWater.splash());

There is an older alternative approach to using prototype, and that is to use the this keyword within your constructor to create a method or property available to all instances of an object. Although I have used that technique in the past, and numerous examples illustrating OOP in JavaScript also use it, I would no longer recommend it. The following is an example for comparison:

var Water = function() {
   this.splash = function(){
      return "Stop splashing me!";
   }
}
var bottledWater = new Water();
alert(bottledWater.splash());

This is all well and good you say, but what if I want to add custom properties and methods to prebuilt JavaScript objects like Array? Any prebuilt object that can be initialized with the new keyword, also has prototype members available. Remember though, you can override a prototype method or property that has already been declared for a prebuilt object, but you should NEVER do this! Just think what would happen if you were using a JavaScript API, and you called the plain old sort() method for an array, only to find out it no longer sorts in dictionary order, but instead sorts in numerical order. Personally, I would be devastated.

We will use playing cards in our example. If you were developing a game API, and you wanted to provide methods and properties for card games that other programmers could use, then prototype is the perfect tool. We could create our own Game object, and that might suit our needs, but you would quickly realize that the JavaScript Array provides much of the prebuilt functionality we already want. We will begin with a full deck of 52 playing cards represented by the abbreviations below.

Array.prototype.deck =
["AS", "AH", "AD", "AC", "KS", "KH",
"KD", "KC", "QS", "QH", "QD", "QC",
"JS", "JH", "JD", "JC", "10S", "10H",
"10D", "10C", "9S", "9H", "9D", "9C",
"8S", "8H", "8D", "8C", "7S", "7H",
"7D", "7C", "6S", "6H", "6D", "6C",
"5S", "5H", "5D", "5C", "4S", "4H",
"4D", "4C", "3S", "3H", "3D", "3C",
"2S", "2H", "2D", "2C"];

Now we know that anytime we call the deck property, we will have access to another array that contains every playing card. An ordered deck of cards fresh from the box is never that useful, but it makes sense to begin with all of our cards, and filter from there depending on the game we are playing. If someone wanted to build a virtual Blackjack table with our API, we would need to start by shuffling that deck, or introduce several decks, and shuffle each one. For example:

Array.prototype.shuffle = function() {
   var a = [];
   var b = this.length;
   for (i = 0; i < b; i++) {
      var e = Math.floor(Math.random() * this.length);
      a[i] = this[e];
      this.splice(e,1);
   }
   return a;
}

Now, anyone using your API can combine the two for their particular card game:

var game = new Array();
alert(game.deck.shuffle());

Think of all the Array properties and methods you can develop moving forward with your API. For instance, you could have a deal() method, and pass it parameters to manage how many players, and how many cards are dealt. Because you use prototype, anyone using your API will be able to access this custom functionality. A game of Poker anyone? Start programming.

Tags: , ,

Posted in: JavaScript

This entry was posted on Friday, June 15th, 2007 at 5:56 am and is filed under JavaScript.

You can follow any responses to this entry through the RSS 2.0 feed.

Both comments and pings are currently closed.

One Response to “Learn to create custom methods and properties for JavaScript objects”

  1. WormE says:

    Thanks for the info, it really made my day a lot easier…

    Cheers!