Creating Your Own JavaScript Objects


You can go only so far using other people's code ”the real power of JavaScript isn't apparent until you begin creating your own JavaScript objects. The following section ”after a brief discussion of object-oriented programming ”describes defining objects, passing arguments, and creating properties and methods .

NOTE

Traditional object-oriented programming languages, such as C++ or Java, have a concept called a class . Classes define the information that an object contains using member variables , which hold data, and the behavior of how the object works using functions called member methods . JavaScript, however, does not contain the formal notion of a class, but approximates its functionality through the use of what are called prototypes . A prototype defines a JavaScript object's initial methods and properties when the object is first created by a script.


Object-Oriented Programming Concepts

Most JavaScript programs written today are created using a style of programming called procedural programming , in which you write a set of related but independent functions that take arguments and perform some useful work to return a result. However, JavaScript is capable of much more than just plain-old functions and variables. It is a complete object-oriented programming language, much like Java or C++. You can create classes of functionality that are reusable across your development work and share them with friends and colleagues.

This section provides a brief introduction to object-oriented programming principles, but it is beyond the scope of this section to cover the entire subject of object-oriented programming and its advanced topics such as inheritance and polymorphism. Several good resources are available on the Internet and at your local bookstore that focus on these subjects.

Defining Classes

Generally speaking, object-oriented programming is a style of programming in which you create and use objects in your programs to represent collections of related functions and data. Instead of writing separate functions to work with a specific piece of data, you define an object that encapsulates data and the functions that manipulate that data all in one place. This way, you can refer to a single object that holds all the relevant information that you need to work with. For example, the JavaScript Date object contains not only the various properties of a date, such as the day and year, but also the various methods needed to work with dates, such as computing the number of days between two dates.

To create a prototype for an object, you begin by writing the object's constructor function. This is the function that will be called when the user creates a new object of the type that you are defining ”in other words, it "constructs" the object. The constructor function has the same name as the object type. For example, to write a constructor function for an object of type Bottle , use this syntax:

 function Bottle()  {  } 

Then, to create a new Bottle object, you would simply use the JavaScript new operator with the object's type:

 var myBottleObject = new Bottle(); 

The preceding example isn't very useful because the Bottle object has no properties or methods associated with it. To give our object some methods and properties, we define them in one of two ways: either within the object's constructor function, or by using the base JavaScript Object's class property called prototype . This example shows both methods.

First method (within the constructor):

 function Bottle()  {     this.bottleSize = 12; // 12 ounce bottle size     this.amountLeft = 12;     this.getAmount = Bottle_getAmount();  } 

Second method (using the prototype property):

 function Bottle()  {  }  Bottle.prototype.bottleSize = 12;  Bottle.prototype.amountLeft = 12;  Bottle.prototype.getAmount = Bottle_getAmount();  function Bottle_getAmount()  {     return this.amountLeft;  } 

In each case, you must provide an implementation for any methods that you define in the prototype. Our example defines one method, getAmount() , which returns the amount of liquid left in the bottle.

Now, a user of our object can simply instantiate a new Bottle object by writing new Bottle() , and the object will automatically receive the default properties and methods.

Passing Arguments to the Constructor

You can also pass default arguments to the constructor. For example, to pass a default size and amount to the Bottle constructor in our preceding example, you would write the following:

 function Bottle(size, amount)  {     this.bottleSize = size;     this.amountLeft = amount;  }  Bottle.prototype.getAmount = Bottle_getAmount();  function Bottle_getAmount()  {     return this.amountLeft;  } 

Now, users of our Bottle object can create Bottle objects of different sizes and amounts. In the revised example, we have used a combination of the "within the constructor" and "object prototype" methods. The member variables are defined in the constructor, whereas the methods are defined using the prototype property. This is a common method of defining objects in JavaScript.

Static Properties and Methods

Not all properties and methods are unique to each object. In our previous example, the properties and methods that we defined were attached to each object that was created and had a distinct value for each separate object. For example, the bottleSize property could be different for each Bottle object that was created.

However, sometimes it is useful to define properties and methods that are common to all objects of a particular type because they won't change from object to object. These types of properties and methods are called static properties and static methods .

To declare a member of a class that is static, you define it not as part of the constructor or class prototype property, but directly as a member of the class. For example, suppose we decided that all of our Bottle objects would have the same manufacturer. We could declare a static property for this by writing the following:

 function Bottle(size, amount)  {     this.bottleSize = size;     this.amountLeft = amount;  }  Bottle.manufacturer = "BigBottleCompany, Inc."; 

This property will now be created whenever a Bottle object is created, just like the other properties, but it will be the same for all Bottle objects. If someone changes the value of a static property or method, then it changes for all objects of that type. To refer to a static property of an object, you precede it with the name of the class, not the name of the object variable. For example:

 var b = new Bottle(12,12);  alert(b.bottleSize) // shows "12"  alert(b.manufacturer) // shows "undefined"  alert(Bottle.manufacturer) // shows "BigBottleCompany, Inc." 

Note that referring to a class property by using the variable that represents an object results in an undefined value.

NOTE

To view the completed code, see Listings 9-1 and 9-2 at the end of this section.


Example: The Inclusion list

This example shows how to implement an inclusion list, like those seen in 9.1.

Figure 9.1. Use an inclusion list to pass values from one select list to another.

graphics/09fig01.gif

This object allows the user to pick values from an "available" list and add or remove them from a "selected" list. Such lists are usually provided to allow a user to choose several entries from a list of available options. This object is actually a compound object; it represents two select lists in a web page as a single object. It also provides the necessary methods for moving items between the two lists.

Start by creating a blank JavaScript page and saving it as inclist.js . In the new document, writing the constructor function for the object first:

 function InclusionList(oFromList, oToList)  {     this.oSourceList = oFromList;     this.oDestList = oToList;  } 

The constructor function takes two arguments, each of which is an object reference to <select> lists in the web page: one acts as the source while the other is the destination.

Next, we declare some global variables to use as error messages:

 var g_sICL_NOSELECTION = "Please select an item to be added."  var g_sICL_NOTHINGTOREMOVE = "Please select an item to be removed." 

Now we need to define the properties and methods that the list object will use. Our list object defines two static properties and four regular (or instance ) methods. The two static properties are error codes that are shown to the user when errors are encountered , such as having nothing selected in the "available" list to add to the "selected" list, or nothing selected in the "selected" list to remove. The four regular methods ”added using the prototype class property ”are responsible for the Add , Add All , Remove , and Remove All functions.

graphics/09icon04.gif

After the properties and methods have been defined, we need to write the implementations for the object's methods. The first method handles the Add method for the object. It detects the selection in the "available" list and copies it over to the "selected" list.

graphics/09icon05.gif

The InclusionList object also supports an Add All function, in which all of the entries in the "available" list are copied over to the "selected" list. This is handled by the icl_AddAll function:

 function icl_AddAll()  {    var i=0;    var sNewItemText='';    var sNewItemValue='';    for (i=0; i < this.oSourceList.options.length; i++)    {      sNewItemText = this.oSourceList.options[i].text;      sNewItemValue = this.oSourceList.options[i].value;      this.oDestList.options[this.oDestList.options.length] = new      Option(sNewItemText,sNewItemValue);    }    this.oDestList.options.selectedIndex =    this.oDestList.options.length-1;  } 

Removing an item from the "selected" part of the Inclusion list deletes the selected entry from the list.

graphics/09icon06.gif

The last method handles the Remove All functionality. Using a while loop, each of the items is, in turn , set to null .

 function icl_ClearItems()  {     while (this.oDestList.options.length) this.oDestList.options[0]     = null;}  } 
Using the Inclusion List

To use the Inclusion list object, you include the JavaScript code in your HTML page using a <script> tag with an src attribute that points to the JavaScript file for the object. Then, you declare a global variable that holds a new instance of the Inclusion list object. The two arguments to the constructor are the two select lists that implement the object.

graphics/09icon07.gif

In the web page, you include a form that contains the two select lists, along with the controls that trigger the Add / Add All / Remove / Remove All functions. The Inclusion list object has been designed to be flexible in that the page elements that control the functionality of the list can be anything that responds to events and can call JavaScript code. In this example, regular form buttons are used to provide the adding and removing functionality, but it could also have been done using image buttons , link text, or anything else that can respond to user events.

graphics/09icon08.gif

That's all there is to it. This example could be improved a bit; for example, there's no error checking to make sure that the same two items in the "available" list aren't included more than once, but this is a functioning example that you can use in your own web pages or extensions.

Listing 9-1 Inclusion List JavaScript File (09_inclist.mxp)
 // JavaScript Document  function InclusionList(oFromList, oToList)  {     this.oSourceList = oFromList;     this.oDestList = oToList;  }  // some global variables used for error messages.  var g_sICL_NOSELECTION = "Please select an item to be added."  var g_sICL_NOTHINGTOREMOVE = "Please select an item to be removed."  InclusionList.ERRMSG_NOSELECTION = g_sICL_NOSELECTION;  InclusionList.ERRMSG_NOTHINGTOREMOVE = g_sICL_NOTHINGTOREMOVE;  InclusionList.prototype.addItem = icl_AddItem;  InclusionList.prototype.addAll = icl_AddAll;  InclusionList.prototype.removeItem = icl_RemoveItem;  InclusionList.prototype.clearItems = icl_ClearItems;  function icl_AddItem()  {     var iItemToAdd = this.oSourceList.selectedIndex;     var sNewItemText='';     var sNewItemValue='';     if (iItemToAdd == -1) {        alert(InclusionList.ERRMSG_NOSELECTION);        return;     }         sNewItemText = this.oSourceList.options[iItemToAdd].text;      sNewItemValue = this.oSourceList.options[iItemToAdd].value;     this.oDestList.options[this.oDestList.options.length] = new     Option(sNewItemText,sNewItemValue);     this.oDestList.options.selectedIndex =     this.oDestList.options.length-1;  }  function icl_AddAll()  {     var i=0;     var sNewItemText='';     var sNewItemValue='';     for (i=0; i < this.oSourceList.options.length; i++)     {        sNewItemText = this.oSourceList.options[i].text;        sNewItemValue = this.oSourceList.options[i].value;        this.oDestList.options[this.oDestList.options.length] = new        Option(sNewItemText,sNewItemValue);     }        this.oDestList.options.selectedIndex =        this.oDestList.options.length-1;  }  function icl_RemoveItem()  {     var iItemToRemove = this.oDestList.selectedIndex;     if (iItemToRemove == -1) {        alert(InclusionList.ERRMSG_NOTHINGTOREMOVE);        return;     }     this.oDestList.options[iItemToRemove]=null;     if (this.oDestList.options.length > 0)        this.oDestList.options.selectedIndex = (iItemToRemove > 0)        ? --iItemToRemove:iItemToRemove;  }  function icl_ClearItems()  {     while (this.oDestList.options.length) this.oDestList.options[0]     = null;  } 
Listing 9-2 Inclusion List HTML File (09_inclist.mxp)
 <html>  <head>  <title>Inclusion List</title>  <meta http-equiv="Content-Type" content="text/html; charset=  iso-8859-1">  <script language="JavaScript" src="inclist.js"></script>  <script>  var g_oICList;  function initialize()  {     g_oICList = new InclusionList(document.forms     ["form1"].source,document.forms["form1"].dest);  }  </script>  </head>  <body onLoad="initialize()">  <form name="form1" method="post" action="">    <table border="0">      <tr>        <td align="center">          <select name="source" size="10" style="width:150px">            <option value="sports">Sports</option>            <option value="stocks">Stocks</option>            <option value="news">News</option>            <option value="weather">Weather</option>            <option value="traffic">Traffic</option>            <option value="realestate">Real Estate</option>           <option value="classifieds">Classifieds</option>           <option value="homegarden">Home &amp; Garden</option>          </select>        </td>        <td align="center">          <p>            <input type="button" name="add" value="Add &gt;"            onClick="g_oICList.addItem()" style="width:100px">            <br>            <input type="button" name="Button" value="Add All            &gt;&gt;" onClick="g_oICList.addAll()"            style="width:100px">            <br>            <input type="button" name="remove" value="&lt; Remove"            onClick="g_oICList.removeItem()" style="width:100px">            <br>            <input type="button" name="clear" value="&lt;&lt;            Remove All" onClick="g_oICList.clearItems()"            style="width:100px">          </p>          </td>        <td align="center">          <select name="dest" size="10" style="width:150px">          </select>        </td>      </tr>    </table>  </form>  </body>  </html> 


Joseph Lowery's Beyond Dreamweaver
Joseph Lowerys Beyond Dreamweaver
ISBN: B000H2MWYS
EAN: N/A
Year: 2001
Pages: 87
Authors: Joseph Lowery

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net