JavaScript Editor Free JavaScript Editor     JavaScript Debugger 




Main Page

Previous Page
Next Page

4.7. Constructors

The capability to create custom objects is what separates modern programming languages from the programming languages of yore. Unfortunately, in JavaScript, this capability is one of those language features that is often either ignored or overlooked. Believe it or not, there is actually a good reason for this; it is all a matter of perception. You see, JavaScript is often viewed as a lightweight language or a kid's programming language, good only for tasks such as creating pop-ups or handling mouseover events.

Although I believe that everybody is entitled to their opinion, I also believe that this opinion has kept web applications mired in their original unload/reload glory. For this reason, as well as the fact that I'm not terribly fond of writing hundreds or thousands of lines of custom code, I began to play around with JavaScript constructors. Yes, with some planning and design work in the beginning, it is very possible to free up some time for the occasional mad scientist project later.

The first question is, how do we start writing a constructor? Do we just jump in and create a constructor and use it? Or should we work out the details of how something works and then use that to write a constructor? Which approach is better?

Tough questions, and, unfortunately, I can't say what will work for you. I can, however, tell you what works for me. Whenever I'm developing a constructor, the first thing that I do is write a sample application that does what I want it to do, but not using a constructor. After the sample application is developed the next step is to rewrite it using a constructor. This might seem like more work than it's worth, but it works for me. Also, I have a tendency to see a better way to accomplish tasks with each subsequent rewrite.

With that explained, let's take a look at some of the coding details of creating JavaScript constructors. I've always been fond of palindromes (words, numbers, or sentences that are spelled the same forward and backward), so let's create a constructor something along those lines. Without further ado, here is an introduction to the two ways of coding class constructors in JavaScript.

Yes, there are two different ways to code class constructors in JavaScript. The first, which is probably the easier of the two, involves creating a function and then creating an instance of that function using the new operator. Listing 4-11 shows an annotated example of using this method to create a constructor.

Listing 4-11. An Annotated Example of Creating a Class Constructor

function Monster(text) {
  /*
     The purpose of the following code is to increment a global
     variable for each instance of this class. In the event of the
     global variable being undefined it will be initialized with a
     value of one.
  */
  try {
    ++_monster;
  }
  catch(e) {
    _monster = 1;
  }

  /*
     This code, which is executed whenever a new instance is
     created, initializes new occurrences of this object. Private
     and public properties are defined and initialized. In
     addition, methods are exposed making them public.
  */
  var occurrence = _monster;                // Private property
  this.string = text;                       // Public property
  this.palendrome = _palendrome;            // Public method
  this.number = _number;                    // Public method

  /*
     The following function is a method which has been made public
     by the above: this.palendrome = _palendrome; statement.
  */
  function _palendrome() {
    var re = new RegExp('[ ,.!;:\']{1,}','g');
    var text = this.string.toLowerCase().replace(re,'');

    return(text == _reverse(text))
  }
  /*
     The following function is a public read only method that gets
     the value of the private property occurrence. Through
     techniques like this it is possible to maintain control over
     the inner workings of objects.
  */
  function _number() {
    return(occurrence);
  }

  /*
     The _reverse function is a private method. Methods are private
     when they are not exposed using the this.[external name] =
     [internal name] statement as _palendrome and _number were.
  */
  function _reverse(string) {
    var work = '';

    for(var i=string.length;i >= 0;i)
      work += string.charAt(i);

    return(work);
  }
}

To instantiate (a fancy way to say "create an instance") this class, all that is necessary is to use the new operator in the following manner:

var myMonster = new Monster();

Using the newly instantiated class is just a matter of using the various public properties and methods that were defined by the constructor. For example, to set and get the string property for the myMonster instance of the Monster class, the code would look like this:

myMonster.string = 'Able was I ere I saw Elba!';
alert(myMonster.string);

To use the properties methods, statements would look like the following:

alert(myMonster.palendrome());
alert(myMonster.number());

However, there is another way to create a class constructor in JavaScript: use the prototype property. This is shown in Listing 4-12.

Listing 4-12. Using the prototype Property to Create an sclass Constructor

Creature.prototype = new Creature;
Creature.prototype.constructor = Creature;

function Creature() {
  /*
     The purpose of the following code is to increment a global
     variable for each instance of this class. In the event of the
     global variable being undefined it will be initialized with a
     value of zero.
  */
  try {
    ++_creature;

    /*
       This is a public property which really shouldn't be accessed
       externally.
    */
    this._instance = _creature;
  }
  catch(e) {
    /*
       Zero is used here due to the fact that this constructor is
    executed at class definition time.
    */
    _creature = 0;
  }
}

Creature.prototype.string;                  // Public property

  /*
     The following function is a method which has been made public
     by the Creature.prototype.palendrome = _Creature_palendrome;
     statement below.
  */
function _Creature_palendrome() {
  var re = new RegExp('[ ,.!;:\']{1,}','g');
  var text = this.string.toLowerCase().replace(re,'');

  return(text == _reverse(text))

  /*
     The _reverse function is a private method available only within
     the enclosing method.
  */
  function _reverse(string) {
    var work = '';

    for(var i=string.length;i >= 0;i)
      work += string.charAt(i);
    return(work);
  }
}
Creature.prototype.palendrome = _Creature_palendrome;

  /*
     The following function is a method which has been made public
     by the Creature.prototype.number = _Creature_Number; statement
     below.
  */
function _Creature_Number() {
     return(this._instance);
}
Creature.prototype.number = _Creature_Number;


Previous Page
Next Page

R7


JavaScript Editor Free JavaScript Editor     JavaScript Debugger


©