Chapter 4
Using Built-In Objects and Custom
Objects
CONTENTS
You learned about the basic principles of object-oriented JavaScript
programming in Chapter 3 "Working with Objects and Events."
This chapter goes into detail about the techniques used in object-oriented
programming. You will also explore the built-in objects you can
use to make JavaScript programming easier, and learn about these
objects using several example programs.
To continue the discussion of object-oriented JavaScript programming,
let's look at the keywords and terms JavaScript uses to represent
objects and other object-oriented concepts, and the ways you can
use them. This will give you a foundation to understand the built-in
objects, which are introduced in the next section.
The basic component of object-oriented programming is, of course,
an object. You can define objects by creating a function to define
them, as you learned in Chapter 3. For example, this function
defines the Card object,
which you worked with in Chapter 3:
function Card(name,address,work,home) {
this.name = name;
this.address = address;
this.work_phone = work;
this.home_phone = home;
this.PrintCard = PrintCard;
}
This function simply defines the name of the object type and assigns
values to each of its functions. It also assigns the name of a
function (PrintCard) as a
method of the Card object.
You can use any variable as a property of an object-in fact, you
can use another object as a property. For example, suppose you
defined an Address object
to hold the different components of an address:
function Address(street1, street2, city, state, zip) {
this.street1 = street1;
this.street2 = street2;
this.city = city;
this.state = state;
this.zip = zip;
}
Because JavaScript doesn't require that you specify variable types,
you don't need to change the definition for the Card
object. It already expects an address and assigns it to the address
property. You can assign an object to this property just as easily.
Here is an example:
tomaddr = new Address("123 Elm Street", "Apartment 312", "Ogden", "UT",
"84404");
tom = new Card("Tom Smith", tomaddr, "555-1239", "555-2394");
Here you have defined an Address
object called tomaddr to
hold Tom's address. Next, you create the Card
object called tom. As the
address parameter, you specify the name of the Address
object.
You now have an object within an object-the tomaddr
Address object is a property,
or child object, of the tom
Card object. The syntax for
accessing these properties is simply to list both objects separated
by periods. For example, if you need to assign a variable to
Tom's zip code, you could use this statement:
z = tom.address.zip;
An object used as a property can have methods also. For example,
you could define a PrintAddress()
method for the Address object
that prints each field of the address:
function PrintAddress() {
document.write("Address:\n");
document.write(this.street1, "\n");
document.write(this.street2, "\n");
document.write(this.city, "\n");
document.write(this.state, "\n");
document.write(this.zip, "\n");
}
You would then link this function as a method of the Address
object by adding this statement to the Address
object's definition:
this.PrintAddress = PrintAddress;
You could then access this method for Tom's address:
tom.address.PrintAddress();
Methods can also be used within other methods. For example, you
could expand the PrintCard()
method to print all the address fields by calling the PrintAddress()
method:
function PrintCard() {
document.write("Name: ", this.name, "\n");
this.address.PrintAddress();
document.write("Work Phone: ", this.work_phone, "\n");
document.write("Home Phone: ", this.home_phone, "\n");
}
This is the syntax you will use any time an object is used as
a property of another object. You will see in Chapter 5 "Accessing
Window Elements as Objects," that the built-in objects used
to represent parts of the browser's display and the Web page use
this technique frequently.
I used the new keyword several
times in the previous examples to create new objects. In object-oriented
terms, you are actually creating an instance of an object class.
Any variable you create with the new
keyword is an instance of that object. The object definition itself
is referred to as the object class, or the object type.
With some built-in objects, such as the String
object, you don't need to use the new
keyword; you simply define a string variable, and JavaScript creates
a String object automatically.
There are other built-in objects with which you can use new.
The this keyword has appeared
in most of the examples. It is simply a shorthand for "the
current object." This is usually used in object definitions,
where it refers to the object being defined, and in method definitions,
where it refers to the object the method is acting on. It can
also be used in event handlers, as you'll see in Chapter 5.
The with keyword is one you
haven't seen before. You can use it to make JavaScript programming
easier-or at least easier to type.
The with keyword specifies
an object, and it is followed by a set of statements enclosed
in braces. For each statement in the set, any properties you mention
without specifying an object are assumed to be for that object.
As an example, suppose you used the Address
object definition given earlier to create an address object called
Fred. You could then use
the following statements to assign values to the Address
object's properties:
with (Fred) {
street1= "12 E 400 S";
street2= "Suite 200";
city="Beverly Hills";
state="CA";
zip="90210"
}
This enables you to avoid typing the object's name (Fred)
at the beginning of each property name: Fred.street1,
Fred.street2, and so forth.
Obviously, the with keyword
only saves a bit of typing in situations like this. However, you
will find it very useful when you're dealing with an object throughout
a large procedure, or when you are using a built-in object, such
as the Math object.
Because JavaScript objects are so flexible, you may wonder why
the constructor function is necessary at all. As a matter of fact,
you can create an object without one by using the Object()
constructor. For example, this statement creates an object called
data:
data = new Object();
Because it isn't any particular kind of object yet, I call it
a generic object. You can add properties to the object
in the usual fashion. This is particularly handy when you are
using the object as an associative array; you'll look at this
technique in Chapter 10, "Working with Multiple Pages and
Data."
The final statement used for object-oriented work in JavaScript
is the for...in loop, which
you looked at briefly in Chapter 3. This loop executes once for
each property of an object, assigning the index variable to the
property name. For example, you could make a simple function to
list the properties of an object and their values, as in List-ing
4.1.
Listing 4.1. A simple example of a for...in
loop.
function list(object) {
for (var i in object) {
document.write("Property: ",i," Value: ",object[i], "<BR>");
}
}
This function uses the variable i
to iterate through the object's properties and uses the document.write()
function to display the property name and the value.
Note |
Notice that I used the syntax object[i] to refer to the property of the object in the previous example. It may seem more obvious to use object.i to refer to the property, but this won't work-JavaScript will interpret this as asking for a
property called i. In order to use the value of i, you need to use brackets.
|
JavaScript includes several built-in objects. They are not part
of the object hierarchy, and they do not represent any part of
a Web page. Instead, they are used for programming functions.
These include the following:
- You can use array objects to store numbered variables.
- You can use String
objects to manipulate strings of characters.
- Date objects enable
you to store and work with dates.
- The Math object includes
methods and properties for mathematical functions.
- The navigator object
stores information about the user's browser and its capabilities.
You will look at each of these types of objects in detail in the
next sections.
Chapter 2 "Working with Larger Programs and Variables,"
introduced the Array object
briefly. The original version of JavaScript did not include arrays,
but they are now a built-in feature. You can create a new Array
object to define an array. (Unlike other variables, arrays must
be declared.) Use the new
keyword to define an array:
students = new Array(30);
This example creates an array with 30 elements, numbered 0
through 29. You can use these
values by addressing their array index:
students[29]="Phred Madsen";
This refers to the last element of the array, index 29.
Array objects have a single property, length.
This provides the number of elements in the array, usually the
same number with which you declared the array. In the array declared
in the previous example, students.length
would return 30.
Note |
When you define an array, its elements are filled with null, or undefined values, up to the length you specify. You can dynamically change an array's size by assigning to the length property.
|
In addition, the array object has three methods:
- join() quickly joins
all the array's elements, resulting in a string. The elements
are separated by commas or by the separator you specify.
- reverse() returns a reversed
version of the array: the last element becomes the first, and
the first element becomes the last.
- sort() returns a sorted
version of the array. Normally, this is an alphabetical sort;
however, you can use a custom sort method by specifying a comparison
routine.
You will see examples of these methods throughout this guide; for
example, in Chapter 15, "Real-Life Examples III," the
sort() method is used to
score poker hands. You will also look at a simple example in the
next section.
Before continuing, let's explore an example of using an Array
object with some of the array methods. Look at the JavaScript
program shown in Listing 4.2.
Listing 4.2. Use of the Array
object and its methods.
// Room for 3 items (0-2)
groceries = new Array(3);
groceries[0]="dental floss";
groceries[1]="baby powder";
groceries[2]="clam chowder";
document.writeln(groceries.join());
document.writeln(groceries.reverse().join());
document.writeln(groceries.sort().join());
This defines an array called groceries,
able to hold 3 items. Next, you assign values to three of the
items. You can then observe the Array
object methods in action with three document.writeln
statements:
- groceries.join() displays
the items separated by commas: "dental
floss,baby powder,clam chowder".
- groceries.reverse().join()
reverses the items, then joins and displays them: "clam
chowder,baby powder,dental floss".
- Finally, groceries.sort().join()
alphabetically sorts the items before displaying them: "baby
powder,clam chowder,dental floss".
You've already used String
objects; any string variable in JavaScript is actually a String
object. You learned about this object briefly in Chapter 3. String
objects have a single property, length.
They also have a variety of methods that you can use to perform
string functions.
The methods of the String
object enable you to convert strings, work with pieces of strings,
search for values, control the string's appearance on the HTML
page, and control HTML links and anchors. You'll look at these
by category in the next sections.
Note |
You don't have to create a string variable to use the String object methods; you can use them on any object with a string value. This includes the text-valued properties of any of the objects in the Web page object hierarchy.
|
String Conversions
Two methods of the String
object enable you to convert the contents of the string easily
to all uppercase or all lowercase:
- toUpperCase() converts
all characters in the string to uppercase.
- toLowerCase() converts
all characters in the string to lowercase.
For example, the following statement displays the value of the
text string variable in lowercase:
document.write(text.toLowerCase());
Note that the statement doesn't change the value of the text
variable. These methods return the upper- or lowercase version
of the string, but they don't change the string itself. All of
the methods of the String
object work in this manner.
One other conversion method is the toString()
method. This one is a bit odd-it can be used with non-string objects.
It is used to explicitly convert them to strings. For example,
if a is a numeric variable
containing the number 500, a.toString()
would return the string "500".
Working with Substrings
Three important String object
methods enable you to work with substrings, or portions
of strings. These methods are useful when you need to split a
string into components or test portions of the string one at a
time.
The first of these is the substring()
method. This returns a string consisting of a portion of the original
string between two index values, which you must specify in parentheses.
For example, the following displays the fourth through sixth characters
of the text string:
document.write(text.substring(3,6));
So where do the 3 and the
6 come from? No, there is
no typo. There are three things you need to know about the index
parameters:
- Indexing starts with 0
for the first character of the string, so the fourth character
is actually index 3.
- The second index is noninclusive. A second index of 6
includes up to index 5 (the
sixth character).
- You can specify the two indexes in either order; the smaller
one will be assumed to be the first index. In the previous example,
(6,3) would have produced
the same result.
As another example, suppose you defined a string called alpha
to hold the alphabet:
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
The following are examples of the substring()
method using this string:
- alpha.substring(0,4)
returns "ABC".
- alpha.substring(10,12)
returns "KL".
- alpha.substring(12,10)
also returns "KL".
Because it's smaller, 10
is used as the first index.
- alpha.substring(6,7)
returns "G".
- alpha.substring(24,26)
returns "YZ".
- alpha.substring(0,26)
returns the entire alphabet.
- alpha.substring(6,6)
returns the null value, an empty string. This is true whenever
the two index values are the same.
The second method for working with substrings is the charAt()
method. This method is simpler: it takes a single index, and returns
a single character. Here are a few examples using the alpha
string defined previously:
- alpha.charAt(0) returns
"A".
- alpha.charAt(12) returns
"M".
- alpha.charAt(25) returns
"Z".
- alpha.charAt(27) returns
an empty string, because there is no character at that index.
The final method for working with parts of strings is probably
the most powerful. The split()
method splits a string into an array of strings, based on a separator
you specify. For example, the following statement splits the components
of a name divided by spaces:
nn = "John Q. Public".split(" ");
After this statement, the nn
array will contain three elements: nn[0]
is "John", nn[1]
is "Q.", and nn[2]
is "Public". This
method is useful any time you need to process a list of items.
Searching a String
The indexOf() method searches
for a string within another string. Use the string you wish to
search for the method call and specify the string to be searched
for in the parentheses. This example searches for "text"
in the temp String
object:
location = temp.indexOf("text");
The value returned to the location variable is an index into the
string, similar to the first index in the substring()
method. The first character of the string is index zero.
You can specify an optional second parameter to indicate the index
value to begin the search. For example, this statement searches
for the word "fish"
in the temp string, starting
with the 20th character:
location = temp.indexOf("fish",19);
Tip |
One use for the second parameter is to search for multiple occurrences of a string. After finding the first occurrence, you search starting with that location for the second one, and so on.
|
A second method, lastIndexOf(),
works the same way, but finds the last occurrence of the
string. It searches the string backwards, starting with the last
character. For example, this statement finds the last occurrence
of "Fred" in the
names string:
location = names.lastIndexOf("Fred");
As with indexOf(), you can
specify a location to search from as the second parameter. In
this case, the string will be searched backward starting at that
location.
Changing a String's appearance
Several methods of the String
object are available for displaying the string in various formats.
These simply return a string consisting of the string enclosed
by certain HTML tags. They do not modify the string itself. Here
are the available attributes, and their equivalent HTML tags:
- String.big() displays
big text, using the <BIG>
tag in HTML 3.0.
- String.blink() displays
blinking text, using the <BLINK>
tag in Netscape.
- String.bold() displays
bold text, using the <B>
tag.
- String.fixed() displays
fixed-font text, using the <TT>
tag.
- String.fontcolor() displays
the string in a colored font, equivalent to the <FONTCOLOR>
tag in Netscape.
- String.fontsize() changes
the font size, using the <FONTSIZE>
tag in Netscape.
- String.italics() displays
the string in italics, using the <I>
tag.
- String.small() displays
the string in small letters using the <SMALL>
tag in HTML 3.0.
- String.strike() displays
the string in a strike-through font, using the <STRIKE>
tag.
- String.sub() displays
subscript text, equivalent to the <SUB>
tag in HTML 3.0.
- String.sup() displays
superscript text, equivalent to the <SUP>
tag in HTML 3.0.
Tip |
There are also two JavaScript functions, escape() and unescape(), which convert strings to URL encoding and back. These are explained in Chapter 17, "Combining JavaScript, CGI, and SSI."
|
Links and Anchors
The link() and anchor()
methods of String objects
can be used to produce HTML for links and anchors. The value of
the string is used as the actual link or anchor value, and the
parameter specifies the link to jump to or the anchor to set.
For example, the following statement sets an anchor called "test"
using the value "This is a Test":
"This is a Test".anchor("test");
and this statement sets a link on the words "Click
Here" to the anchor defined previously:
"Click Here".link("#test");
The Date object is a built-in
JavaScript object that enables you to conveniently work with dates
and times. You can create a Date
object any time you need to store a date, and use the Date
object's methods to work with the date.
Strangely, the Date object
has no properties. To set or obtain values from a Date
object, you must use the methods described in the next section.
Note |
JavaScript dates are stored as the number of milliseconds since January 1st, 1970, at midnight. This date is called the epoch. Dates before 1970 aren't allowed. This means I
can't store my birthday in a Date object, and there's a good chance you can't either. Hopefully, this will be fixed in a future version of JavaScript. In the meantime, you can work with dates manually, using strings or numeric variables.
|
Creating a Date Object
You can create a Date object
using the new keyword. You
can also optionally specify the date to store in the object when
you create it. You can use any of the following formats:
birthday = new Date();
birthday = new Date("June 20, 1996 08:00:00");
birthday = new Date(6, 20, 96);
birthday = new Date(6, 20, 96, 8, 0, 0);
You can choose any of these formats, depending on which values
you wish to set.
If you use no parameters, as in the first example, the current
date is stored in the object. You can then set the values using
the set methods, described
in the next section.
Setting Date Values
A variety of set methods
enable you to set components of a Date
object to values:
- setDate() sets the day
of the month.
- setMonth() sets the month.
JavaScript numbers the months from 0 to 11, starting with January
(0).
- setYear() sets the year.
- setTime() sets the time
(and the date) by specifying the number of milliseconds since
January 1st, 1970.
- setHours(), setMinutes(),
and setSeconds() set the
time.
Getting Date Values
You can use the get methods
to get values from a Date
object. This is the only way to obtain these values, because they
are not available as properties:
- getDate() gets the day
of the month.
- getMonth() gets the month.
- getYear() gets the year.
- getTime() gets the time
(and the date) as the number of milliseconds since January 1st,
1970.
- getHours(), getMinutes(),
and getSeconds() get the
time.
Working with Time Zones
A few functions are available to help you work with local time
values and time zones:
- getTimeZoneOffset() gives
you the local time zone's offset from GMT (Greenwich Mean Time,
also known as UTC).
- toGMTString() converts
the date object's time value to text, using GMT.
- toLocalString() converts
the date object's time value to text, using local time.
Converting Between Date Formats
Two special methods of the Date
object enable you to convert between date formats. These are not
methods of individual Date
objects; instead, you use them with the built-in object Date
itself. These include the following:
- Date.parse() converts
a date string, such as "June 20,
1996" to a Date
object (number of milliseconds since 1/1/1970).
- Date.UTC() is the opposite:
it converts a Date object
value (number of milliseconds) to a UTC (GMT) time.
The Math object is a bit
different from the String
and Date objects: it is a
built-in object in itself, rather than an object class of which
you can create instances. In other words, you can't create your
own Math objects. The Math
object exists automatically in any JavaScript program and encapsulates
all of JavaScript's math capabilities.
The Math object's properties
represent mathematical constants, and its methods are mathematical
functions.
Note |
Because you may use the Math object's properties and methods throughout an entire group of statements, you may find it useful to use the with keyword, introduced earlier in this chapter, to specify the Math object for those
statements.
|
I will introduce some highlights of the Math
object's methods in the following sections. For a complete list
of the properties and methods of this object, including trigonometric
and logarithmic functions, refer to appendix A.
Rounding and Truncating
Three of the most useful methods of the Math
object enable you to round decimal values up and down:
- Math.ceil() rounds a
number up to the next integer.
- Math.floor() rounds a
number down to the next integer.
- Math.round() rounds a
number to the nearest integer.
All these take a single parameter: the number to be rounded. You
might notice one thing missing: the ability to round to a decimal
place, such as for dollar amounts. You can easily simulate this,
though. Here's a function to round to two decimal places:
function round(num) {
return Math.round(num * 100) / 100;
}
This function multiplies the value by 100 to move the decimal,
then rounds the number to the nearest integer. Finally, the value
is divided by 100 to restore the decimal. You'll use this function
in an automatic order form in Chapter 6 "Using Interactive
Forms."
Generating Random Numbers
One of the most commonly used methods of the Math
object is the Math.random()
method, which generates a random number. This method doesn't require
any parameters. The number it returns is a random decimal number
between 0 and 1.
You usually will want a random number between 1 and a value. You
can do this with a general purpose random number function like
this:
function rand(num) {
return Math.floor(Math.random() * num) + 1;
}
This function multiplies a random number by the value you send
it, then converts it to an integer between 1 and the number using
the Math.floor() method.
The navigator object is a
special object that stores information about the version of the
browser. This is a Netscape-specific tag, and it may or may not
be implemented in other browsers. (This may make you question
its usefulness.)
The navigator object doesn't
technically qualify as a built-in object, because it represents
a physical entity-the browser in use. In this way it's similar
to the objects, such as window
and document, which you will
look at in Chapter 5. Because it isn't really part of the object
hierarchy either, you'll examine it here.
The navigator object includes
several properties that reflect information about the version
of Netscape in use. These are all read-only properties:
- navigator.appcodeName
is the browser's code name, usually "Mozilla".
- navigator.appName is
the browser's name, usually "Netscape".
- navigator.appVersion
is the version of Netscape being used-for example, "2.0(Win95;I)".
- navigator.userAgent is
the user-agent header, which is sent to the host when requesting
a Web page. It includes the entire version information, "Mozilla/2.0(Win95;I)".
Note |
One use for the navigator object is to check for a particular version of Netscape; this is most useful if you are using a feature that was recently added and want to include an alternative for users of older versions.
|
There are also several properties of the navigator
object that deal with Java, plug-ins, and multimedia documents:
- navigator.javaEnabled
indicates whether Java is enabled in the browser.
- navigator.plugIns is
a list of the currently available plug-ins.
- navigator.mimeTypes is
a list of the currently available MIME types.
- navigator.taintEnabled() indicates
whether data tainting (see Chapter 10) is enabled.
Because these last two properties deal with plug-ins and multimedia,
you'll take a closer look at them in Chapter 13, "Working
with Multimedia and Plug-Ins." The navigator.javaEnabled
property is described in detail in Chapter 16, "Integrating
JavaScript with Java."
Along with the various built-in objects, you can also create objects
of your own. You've already seen the basic example of doing this
with the new keyword:
var = new ObjectType(parameters);
This assumes you have created an object definition for the object.
Once you've done this, you can work with the properties and methods
of the object, just like the built-in objects.
In object-oriented terms, the object definition defines a prototype
for the object. This is the set of rules that govern how an object
works. JavaScript provides a prototype
keyword, which enables you to modify the prototype of all objects
of a certain class.
As an example, suppose you defined an object called lunch
with the following properties:
lunch.sandwich
lunch.drink
lunch.fruit
You could then create a lunch
object like this:
mylunch = new lunch("bologna","coke","banana");
As you saw in other chapters, you could then add a property to
the object:
mylunch.dessert = "pie";
With a prototype, though, you can add a property to the object
definition itself. This command will add the dessert
property to all existing and future lunch
objects:
lunch.prototype.dessert = "cake";
Any lunch object created
after this point will include this property, with a default value
of "cake". The
property will also be added to existing lunch
objects. You can also extend the prototypes of the built-in objects,
as you'll see in the next example.
A powerful feature of the prototype
keyword is the capability of extending the definitions of built-in
objects. If you think the String
object doesn't quite fit your needs, you can extend it, adding
a new property or method.
As an example, let's add a method to the String
object definition. There are a few methods, such as big(),
blink(), and bold(),
that output HTML tags with the string, but there is no method
to work with headers. Listing 4.3 adds a head()
method to the String object
definition that will display the string as a heading.
Listing 4.3. Adding a method to the String
object.
//define the function
function addhead (level) {
html = "H" + level;
text = this.toString();
start = "<" + html + ">";
stop = "</" + html + ">";
return start + text + stop;
}
//add the method to the String prototype
String.prototype.head = addhead;
//test it
document.write ("This is a test".head(1));
First, you define the addhead()
function, which will serve as the new string method. It accepts
a number to specify the heading level. The start
and stop variables are used
to store the HTML begin and end header tags, such as <H1>
and </H1>.
After the function is defined, you simply use the prototype
keyword to add it as a method of the String
object. You can then use this method on any String
object; this is demonstrated by the last statement, which displays
a quoted text string as a level-one header.
In this chapter, you learned the details of JavaScript's object-oriented
capabilities, the various keywords used for working with objects
in JavaScript, and techniques for working with objects and properties.
You also learned about the built-in objects that aren't directly
related to Web pages:
- The String object for
working with strings
- The Date object for date-related
functions
- The Math object for math
functions
- The navigator object
for information about the browser
- Creating custom objects, and customizing existing ones
You can now learn about the JavaScript object hierarchy and more
advanced features:
- To learn about the object hierarchy, which enables you to
work with Web page elements, see Chapter 5 "Accessing Window
Elements as Objects."
- To learn to use the objects to work with HTML forms, see Chapter
6, "Using Interactive Forms."
- To review the basics of JavaScript objects, see Chapter 3
"Working with Objects and Events."
- To see some of the techniques in this chapter in action, see
Chapter 7 "Real-Life Examples I."
- To learn techniques for perfecting and debugging your JavaScript
programs, see Chapter 14, "Debugging JavaScript Programs."
Q: | Do you really need to use objects within objects? Is there any practical reason to do this?
|
A: | JavaScript programs are usually simple, and you probably won't need data structures that are complicated very often. However, the object hierarchy--which you'll learn about in Chapter 5--uses these techniques heavily.
|
Q: | Most of the string appearance methods, such as string.big, take almost as much typing as simply including the appropriate HTML codes.
Why would I use these?
|
A: | One reason is that they may be more readable if someone (including you) needs to read through the source code later. Another reason is that the HTML specification may change;
presumably, future versions of JavaScript will use the appropriate codes for new versions of HTML, so you won't have to worry about updating your program.
|
Q: | Is there any limit to the length of a string variable in JavaScript?
|
A: | Strictly speaking, no. The only limitation is the memory available on the user's machine. You should keep lengths to a minimum, though, to avoid crashing the browser.
|
|