Previous Contents
11. Creating Objects

Throughout this tutorial you have used most of the objects provided by JavaScript to help you manage your web pages and to create interaction with your users. Now it's time to learn how to create your own objects. By doing so you can extend the usefulness of JavaScript beyond the built-in windows and documents that comprise the web environment. You can begin modeling real-world objects and using these components to develop your own applications.

To get an idea of where we're going, click on the button below to view the final output of the application to be developed.

This output is typical of an order system that produces sales orders or invoices. It is not "real-world" in the sense that it could be used in a production environment; it is "real-world," though, in the sense that to produce it you must model reality in terms of objects that can be manipulated by a computer.

The Application Development Process

In order to develop an application like this in JavaScript you need proceed through the five steps listed below:
  1. Identify the Objects. First, you need to determine which "real-world" objects and their relevant characteristics comprise the application. This involves thinking about the "nouns" of the application--the people, places, and things--that are brought together and associated in various ways to produce the desired results. This is not particularly a JavaScript requirement; it needs to be done regardless of the scripting or programming environment. It is simply a way of generating a logical model of physical reality, since computers can't process actual things.
  2. Define Object Classes. Second, you need to define the JavaScript classes that represent the previously identified objects. This step gives you the models (the blueprints) for creating the JavaScript objects, and their properties, that will be involved in the application.
  3. Define Object Methods Third, you create any methods, or actions, associated with the objects--ways in which the object classes can produce new, additional properties resulting from, say, arithmetic or string manipulations of the original properties.
  4. Create Object Instances. Fourth, you need to create instances of the previously defined object classes. Based on the object blueprints, you produce "data-filled" objects that can be manipulated by your application.
  5. Process Object Instances. Fifth, you develop the code to process the object instances and produce the desired results. This involves accessing object properties and methods and applying appropriate arithmetic and string operations within appropriate decision-making and program-control structures. It also involves generating and displaying output results.
We will proceed through each of these steps in writing the sales order application whose output was shown above.

1. Identify the Objects

Possibly the most difficult part of the application development process is deciding what objects are involved. By this we don't mean which JavaScript objects, but which real-world objects. There's so many to choose from! The methodologies of system modeling are well beyond the scope of this tutorial, so we'll have to cheat a little and give you help with the objects appropriate to this application.

In an order processing application there are two very obvious real-world objects involved. First, there is a customer. This is the "object" to which sales are made. And second, there is a product. This is the "object" that is sold to the customer. A sales order, then, is a collection of associations between customer objects and product objects: each customer purchases one or more products. Each of these associations suggests a third object: an order item. This object represents a particular customer purchasing a quantity of a particular product. Once you put together a customer object with a collection of order item objects--each of which is associated with a particular product object, you have generated a sales order. You have, in fact, modeled a real-world situation in terms of objects and their associations.

What, then, are the characteristics--the properties--of these three objects? A customer can have any number of characteristics. Some of these properties are irrelevant to ordering products: height, weight, sex, make of car, political affiliation. Other properties are relevant: name, address, phone number, credit rating, and the like. To keep things simple, let's define a customer object as having two pertinent properties: name and customer number (which we'll assign). These two properties represent enough information to characterize and distinguish one customer from another, which we'll need to do if we expect more than one customer.

What about the properties of a product? Again, there are any number of ways to characterize this object: size, weight, color, components, manufacturer, and the like. Let's use two: description and price. This, also, is sufficient information to distinguish one product from another, which we'll need to do if we handle more than one product.

Finally, we need to determine the relevant properties of the order item object. For our purposes let's consider an order item object to be made up of four properties: a quantity ordered, a product description, a product price, and an item amount (representing the quantity ordered multiplied times the product price). Note that two of these properties--the product description and the product price--are properties themselves of the product object. So, an order item object is actually comprised of three properties, one of which is an object itself (more about this in a moment).

In mentioning the item amount property, we have foreshadowed a method associated with the order item. This amount is given by multiplying (quantity * price); that is, the quantity ordered property of order item is multiplied times the product price property of product as a "method" of deriving the quantity ordered property of order item. Thus, order item can now be viewed as having three properties, one of which is an object and one of which is a method (more about this in a moment, as well).

Figure 11-1 shows graphically the objects, properties, methods, and associations that exist for this application. A customer object and its associated properties are combined with multiple order item objects and their properties to compose a customer sales order. An order item object, in turn, is composed of properties, one of which is a product object and one of which is an amount method.


Figure 11-1. Objects and Relationships in Sales Order Application


 

2. Define Object Classes

Now that we understand, generally, the objects, properties, and methods that need to be combined to produce this application, we need to turn them into JavaScript language. We need, specifically, to create the object classes that will be the models, or blueprints, for constructing the actual objects used in the application.

Object classes are defined with special JavaScript functions. The function names the object and its properties, and provides arguments for sending actual data to the function when creating instances of the object. Since most of the conceptual work of identifying objects was done in the preceding step, turning the objects into JavaScript classes is relatively easy. The function to create the customer object class is shown below:

function Customer ( cName, cNumber )
{
    this.CustName = cName
    this.CustNumber = cNumber
}

This object is assigned the name Customer and it is given two properties (by use of the keyword this.) named CustName and CustNumber. This function doesn't create any actual objects; it does, however, provide the model for their creation when data are passed to the function. As you can tell from its arguments, the function will receive two data items: a customer name and a customer number. When the function is called and these values received, the function creates the actual customer object.

Easy enough. Now let's look at the product object class:

function Product ( pDescription, pPrice )
{
    this.ProdDescription = pDescription
    this.ProdPrice = pPrice
}

This code defines object class Product containing two properties named ProdDescription and ProdPrice. An actual instance of the object is created when the function is passed two data values, one for the description and one for the price.

Finally, we define the third object of our application, the order item:

function OrderItem ( oQuantity, oProduct )
{
    this.OrderQty = oQuantity
    this.OrderProduct = oProduct
    this.OrderAmount = CalcAmount
}

The object class OrderItem contains three properties: The OrderQty is passed to the function and represents the number of items ordered. The OrderProduct is passed to the function and represents the product that is ordered (when creating an instance of this class, what will be passed here is the Product object containing the ProdDescription and ProdPrice properties). The OrderAmount property is not passed to the function but is provided by a method named CalcAmount (yet to be defined).

3. Define Object Methods

All that remains is to define any methods associated with the objects. A method is associated with an object by generating a property for that object. In our case, there is one method, associated with the OrderItem object, to produce a property named OrderAmount. The property specification:

this.OrderAmount = CalcAmount

signifies that a method named CalcAmount is to be called to return a value for this property. (Actually it won't mean that until after the method is defined.) So, let's make that method:

function CalcAmount ( )
{
    return (this.OrderQty * this.OrderProduct.ProdPrice)
}

A method is defined in a similar way to an object class, through use of a function. This method is named CalcAmount and it returns a value, based on a calculation, when called. The calculation uses:

this.OrderQty - a reference to the OrderQty property it receives from the associated (this.) OrderItem object, and

this.OrderProduct.ProdPrice - a reference to the OrderProduct property it receives from the OrderItem object and, through this property to the ProdPrice property of and Product object.

You may have to think about this for a minute. Just remember that object OrderItem contains the property OrderProduct , that is actually the object Product, that contains the property ProdPrice.


Figure 11-2. Relationships Among Object Properties

Now we have defined all the objects, properties, and methods necessary for our application to work. With the conceptual and definitional tasks out of the way, we are ready to create actual working objects to implement the application.

4. Create Object Instances

To create object instances means, in this case, to start taking orders from customers. So, let's create an instance of a Customer object so we'll have somebody to sell to.

Object instances are created by calling the appropriate object class function and passing to it the data with which to make an instance of that object. To create a Customer object, then, you use a JavaScript statement in the format:

var varName = new Customer ( nameValue, numberValue )

That is, you create a new variable varName (an object instance) and assign to it a new instance of the Customer class. This new instance is created by the Customer function using the values passed to it: nameValue and numberValue. The most direct way to do this is to pass literal values:

var Customer1 = new Customer ("Richard Robert Looney", "987-65-4321-0")

At this point, you have an object instance with two properties, representing an actual customer. The Customer object class has been turned into a Customer object instance:

Customer1
    CustName = "Richard Robert Looney"
    CustNumber = "987-65-4321-0"

We can quickly do the same for the Product class:

var Product1 = new Product ( "Lead Pipe", 5.95 )
var Product2 = new Product ( "Black Powder", 19.25 )
var Product3 = new Product ( "Fuse Cord", 5.55 )
var Product4 = new Product ( "Bandages", 1.75 )

and end up with four products to sell:

Product1
    ProdDescription = "Lead Pipe"
    ProdPrice = 5.95

Product2
    ProdDescription = "Black Powder"
    ProdPrice = 19.25

Product3
    ProdDescription = "Fuse Cord"
    ProdPrice = 5.55

Product4
    ProdDescription = "Bandages"
    ProdPrice = 1.75

Of course, you wouldn't normally create objects through literal assignments. You would provide a data entry form so an operator could enter the data that would be passed along to the function creating the objects. We're assigning literal values here to remove the data entry complications from consideration.

Now that we have an actual customer and actual products to sell, we can create the instances of OrderItems. Again, we will bypass the formalities of data entry forms and operators and and assign literal values:

var OrderItem1 = new OrderItem ( 7, Product1 )
var OrderItem2 = new OrderItem ( 3, Product2 )
var OrderItem3 = new OrderItem ( 3, Product3 )
var OrderItem4 = new OrderItem ( 9, Product4 )

Four order items are created for this customer. Let's take a look at what happens when one of these statements is executed.

As before, an instance is created from a class. For object instance OrderItem1the OrderItem object class is called and passed two values: the numeric value 7 becomes the OrderQty property; the variable Product1 (a previously created instance of the Product object) becomes the OrderProduct property. Finally, property OrderAmount is assigned the value returned from the CalcAmount method, which multiplies OrderQty (7) * OrderProduct.ProdPrice (5.95) = 41.65. It's as if OrderItem1 and the remaining OrderItem instances had the structure:

OrderItem1
    OrderQty = 7
    OrderProduct [Product1]
        ProdDescription = "Lead Pipe"
        ProdPrice = 5.95
    OrderAmount [CalcAmount] = 41.65

So far, our scripts associate customers with products to produce order items; plus, the necessary arithmetic to compute line-item amounts is built into the associations as a method. Most of the data processing for this application is completed. All that remains is to calculate a final total for the order (an operation that was not defined as a method associated with the previous objects) and to prepare the information for display.

5. Process Object Instances

We are ready now to get the information in a format that can be displayed in a window document. In order to collect together and organize the values to be displayed in a little handier fashion (and to save some typing effort later) we'll first of all define a set of standard variables to hold the output values:

var CustName = Customer1.CustName
var AccountNo = Customer1.CustNumber

var Quantity1 = OrderItem1.OrderQty
var Description1 = OrderItem1.OrderProduct.ProdDescription
var Price1 = OrderItem1.OrderProduct.ProdPrice
var Amount1 = OrderItem1.OrderAmount ( )

var Quantity2 = OrderItem2.OrderQty
var Description2 = OrderItem2.OrderProduct.ProdDescription
var Price2 = OrderItem2.OrderProduct.ProdPrice
var Amount2 = OrderItem2.OrderAmount ( )

var Quantity3 = OrderItem3.OrderQty
var Description3 = OrderItem3.OrderProduct.ProdDescription
var Price3 = OrderItem3.OrderProduct.ProdPrice
var Amount3 = OrderItem3.OrderAmount ( )

var Quantity4 = OrderItem4.OrderQty
var Description4 = OrderItem4.OrderProduct.ProdDescription
var Price4 = OrderItem4.OrderProduct.ProdPrice
var Amount4 = OrderItem4.OrderAmount ( )

var Total = (Amount1 + Amount2 + Amount3 + Amount4)

This step isn't really necessary but it does result in shorter variable names to type when formatting the order form for display. Of course, the last statement is necessary since it calculates the order total, an output value that had not yet been produced. You should notice from the above listing that we have pretty much described how all values will appear on the final document. Plus, note the way in which the Amounts are specified: var Amount1 = OrderItem1.OrderAmount ( ). This is using the dot format to specify a method that returns the value.

By the way, all of the JavaScript commands presented so far can appear within a single script. The operations take place automatically and in the order given (recognizing that in actual practice this would not be the case). Even if you linked this script, or any collection of "subscripts," to buttons, clicking on the buttons would produce no discernable results. None of the processing so far produces anything visual.

We will, however, package the output phase of processing as a named function and associate it with a button. We don't want the output displayed automatically when the web page is opened. Below is that function to produce the final sales order along with a button to display it. The scripting could have been more compact, but readability is the watchword.

function PrintOrder ( )
{
    Win1 = open ("", "secondary", "width=400,height=300")
    Win1.document.open ( )
    Win1.document.write ("<TABLE WIDTH=370 BGCOLOR=SILVER>")
    Win1.document.write ("<TD><FONT SIZE=5 COLOR=WHITE><CENTER>")
    Win1.document.write ("Arson Supply Company")
    Win1.document.write ("</CENTER></FONT></TD>")
    Win1.document.write ("</TABLE>")
    Win1.document.write ("<HR SIZE=1>")
    Win1.document.write ("<FONT COLOR=BLUE>Customer Name:    </FONT>")
    Win1.document.write (CustName + "<BR>")
    Win1.document.write ("<FONT COLOR=BLUE>Customer Number: </FONT>")
    Win1.document.write (AccountNo + "<P>")
    Win1.document.write ("<TABLE BORDER WIDTH=370 BGCOLOR=SILVER>")
    Win1.document.write ("<TR>")
    Win1.document.write ("<TD WIDTH=15%><FONT COLOR=BLUE>Qty.</TD>")
    Win1.document.write ("<TD WIDTH=60%><FONT COLOR=BLUE>Description</TD>")
    Win1.document.write ("<TD WIDTH=15%><FONT COLOR=BLUE>Price</TD>")
    Win1.document.write ("<TD WIDTH=15%><FONT COLOR=BLUE>Amount</TD>")
    Win1.document.write ("<TR>")
    Win1.document.write ("<TD>" + Quantity1 + "</TD>")
    Win1.document.write ("<TD>" + Description1 + "</TD>")
    Win1.document.write ("<TD>" + Price1 + "</TD>")
    Win1.document.write ("<TD>" + Amount1 + "</TD>")
    Win1.document.write ("<TR>")
    Win1.document.write ("<TD>" + Quantity2 + "</TD>")
    Win1.document.write ("<TD>" + Description2 + "</TD>")
    Win1.document.write ("<TD>" + Price2 + "</TD>")
    Win1.document.write ("<TD>" + Amount2 + "</TD>")
    Win1.document.write ("<TR>")
    Win1.document.write ("<TD>" + Quantity3 + "</TD>")
    Win1.document.write ("<TD>" + Description3 + "</TD>")
    Win1.document.write ("<TD>" + Price3 + "</TD>")
    Win1.document.write ("<TD>" + Amount3 + "</TD>")
    Win1.document.write ("<TR>")     Win1.document.write ("<TD>" + Quantity4 + "</TD>")
    Win1.document.write ("<TD>" + Description4 + "</TD>")
    Win1.document.write ("<TD>" + Price4 + "</TD>")
    Win1.document.write ("<TD>" + Amount4 + "</TD>")
    Win1.document.write ("<TR>")
    Win1.document.write ("<TD COLSPAN=3><FONT COLOR=BLUE>Total</TD>")
    Win1.document.write ("<TD>" + Total + "</TD>")
    Win1.document.write ("</TABLE>")
    Win1.document.close ( )
}

If you would like to see the output along with the complete code, click on the button below for a side-by-side framed presentation of both:

We cheated a little on the input values so that the resulting numbers would not end in zero nor would they carry to more than two decimal positions. JavaScript does not format floating-point numbers very elegantly (really, at all) so it's virtually impossible to work with dollars and cents and end up with only two decimal positions. JavaScript wants to carry decimals to machine capacities. Plus, there is no way to align values to the right of a field. Perhaps in future versions of the language there will be better formatting capabilities to go along with the useful capacity to create your own objects.


Previous Contents