<%response.buffer=true%> <% yere = year(date()) Response.Expires = 0 %> JavaScript Intro
<objects>
  spacerspacer

JavaScript Objects

We've worked with many objects provided by JavaScript, for example the Date() object. To use the Date() object, we need to declare an 'instance' (example) of the Date() object:

var myDate = new Date();

Once we have an instance of the object (myDate) we can request data from the object (as long as we know how to ask):

alert(myDate.getFullYear());

The getFullYear() method provides us the current year, in a 4 digit format, which we used to display copyright data with document.write(). Remember when we see the tell-tale parens (), we know we're dealing with a method, not a property. We'll see properties first, as we create our own objects.

Car Object: We'll examine the fundamentals of creating our own JS objects by building a trivial 'car' object. We create the object by building a function that will build (construct) the car object:

function Car(sColor, iDoors, iMpg)
{//constructor for Car object
      this.color = sColor;
      this.doors = iDoors;
      this.mpg = iMpg;
      this.drivers = new Array("Mike", "Sue");
}

There are three parameters that enter into the creation of the object, sColor, iDoors, iMpg. The data thus entering the object become properties of the object, and become attached to the object by the reference to this:

this.color = sColor;

The theoretical 'color' of the car is thus attached to our car object. The function that builds this object is called a constructor, because it builds or 'constructs' objects. We can create an instance (example) of our car object:

var myCar = new Car("red",2,30);

The info coming into the constructor function imply the car is red, has 2 doors, and gets 30 MPG. Once the object is thus created, we can view the data stored in the properties of our car object:

alert('We have a pretty ' + myCar.color + ' car. It has ' + myCar.doors + ' doors. It gets ' + myCar.mpg + ' MPG.');

There is even an array that is attached to the object. We can loop to view the data inside:

var myOutput = '';
for(x=0; x<myCar.drivers.length;x++)
{
      myOutput += ' ' + myCar.drivers[x];
}
alert('Our car has ' . myCar.drivers.length . ' drivers. They are: ' + myOutput);

Methods: There will be times we wish to create methods in our object that allow us more control or perhaps to have our object perform actions. The syntax of adding methods in an efficient manner in JS is odd. Here is an example method we could add to our car object:

if(typeof Car._initialized == "undefined")
{//prevents creation of multiple instances of static function
      Car.prototype.showColor = function()
      {
          return this.color;
      }
}

Since a method is essentially a 'set of instructions', we don't need a new 'set' for every object. Therefore we can check to see if a Car object already exists in memory. If it does not, we'll create a function named showColor(), and attach it to every possible Car object created, going forward. This method is shared between each instance of a Car object via the prototype property of all JS objects. The simple data produced by the method is as follows:

return this.color;

So, the method is trivial, and in our case does nothing more than return the same data as the color property:

alert('We have a pretty ' + myCar.showColor() + ' car!');

Here is our first car example: carObj1.htm

A More Realistic Method: Here is a bit of code from our second version of the car object. In it we vary the cost of the object based upon data provided when the object is created:

if(typeof Car._initialized == "undefined")
{//prevents creation of multiple instances of static function
      Car.prototype.showCost = function()
      {
            var cost = 0;
            switch(this.model)
            {
                  case "Corvette":
                  cost += 50000;
                  break;

                  case "Hummer":
                  cost += 100000;
                  break;

            }

           switch(this.engine)
            {
                  case "V8":
                  cost += 0;
                  break;

                  case "V12":
                  cost += 5000;
                  break;

            }

      if(this.stereo){cost += 1000;}
            return cost;
      }
}

The showCost() method above gives us more realistic method: carObj2.htm Version 3 adds a another function, subtractDownPayment(): carObj3.htm

Arrays of Objects: In version 4 of our car object demo we store our objects in a set, as an array. We can build an "empty" array, then use a method of the Array object to push() new objects on the Array:

var aCars = new Array();
aCars.push(new Car("Corvette","red","V8",true));
aCars.push(new Car("Hummer","black","V12",true));

Once we have all the cars in the array, let's build a new function to show all the properties & methods of a single car:


function showCar(myCar)
{//shows info about car object

      myOutput = '<font color="' + myCar.color + '">Model: <b>' + myCar.model + '</b><br />';
      myOutput += 'Color: <b><font color="' + myCar.color + '">' + myCar.color + '</b><br />';
      myOutput += 'Engine: <b>' + myCar.engine + '</b><br />';
      myOutput += 'Stereo (Y/N): <b>' + myCar.stereo + '</b><br />';
      myOutput += 'Drivers: <b>' + myCar.drivers + '</b><br />';
      myOutput += 'Cost: <b>$' + myCar.cost.toFixed(2) + '</b><br />';
      myCar.subtractDownPayment(20000);
      myOutput += 'After downpayment is subtracted: <b>$' + myCar.cost.toFixed(2) + '</b></font><br />';
      return myOutput;
}

Then, we can loop through the array, and apply the new showCar() function to our car array:

myOutput = "";
for(x = 0; x < aCars.length; x++)
{
      myOutput += showCar(aCars[x]);
}

myOutput += "<br /><br />";
document.getElementById("carDiv").innerHTML = myOutput;

Here's carObj4.htm.

StringBuffer: Now let's look at a more useful object, named StringBuffer. This example comes from Nicholas Zakas Excellent book, Professional JavaScript for Web Developers.

In many programming languages, it's more efficient to 'tack' arrays together into a single 'string' than it is to continually concatenate string data to the same variable. This is because whenever a string is built by continually concatenating, the space in memory to be used is not known in advance, and most languages copy data back and forth between memory locations frequently.

It's usually more efficient to build an array, then place a new item in the array for every new 'string'. Then when all the pieces of data are

function StringBuffer()
{//constructor for StringBuffer object
      this.strings = new Array;
      if(typeof StringBuffer._initialized == "undefined")
      {//prevents creation of multiple instances of static function
            StringBuffer.prototype.append = function(str)
            {//add new string to array
                  this.strings.push(str);
            }
            StringBuffer.prototype.toString = function(str)
            {//returns joined strings
                  return this.strings.join("");
            }
      }
}

You can see by the comparison to the standard string concatenation how much speed can be gained: stringBufferObj.htm

nmValid: Sometimes objects are born, not made. The next example is a work in progress, and an extension of our previous work validating forms.

In previous examples of form validation, we created a function named checkForm() and passed the form, data and all to the function via the keyword this. Then we used a series of standalone functions, checkText(), checkRadio() & checkSelect() along with other more specific functions using regular expressions to check for valid emails etc. In each case we exited the checkForm() function, returned false and provided feedback to the user via alerts, if there was a problem.

This is all fine, except lately it has been in vogue to provide feedback to the user in a more integrated way. So, instead of using alerts as our primary means of feedback, we could create a div with an id of ErrorDiv, which we’ll load with an array of error messages determined by JS form validation functions: error_div_1.htm

Due to the large number of global variables declared outside the functions, (errorColor, altErrorColor, etc.) this situation begs consideration of creating a form validation object. If we create an object, all of our ‘state’ related items like the array of errors, can be stored internally, (encapsulated) where we won’t trip on them. Once we place the functions inside the object as methods, we can consolidate all of the functions into a single validation method. We’ll rely on the fact that we can interrogate the elements via the type property and not make the programmer work with separate methods for each type of form element: error_div_4.htm

Work on this continues: nmValid

   
Print this Page Back To Top

2000- <%=yere%> newMANIC INC, All rights reserved