3.0 Introduction
Most programming tasks involve moving
data around in memory. A lot of the data involved in browser-based
JavaScript activity consists of objects that are part of the rendered
document. But very often your scripts arrive at the client
accompanied by data provided by a server or hardwired in the script
(as arrays or custom objects). Or, you may find it convenient to
create more flexible data structures that mirror the rendered content
on the page. For example, it may be easier and faster to sort a
table's data inside a JavaScript array and re-render
the table rather than playing Tower of Hanoi games with cells and
rows of a table one by one.
One of the most important jobs you have as a programmer is designing
the data structures that your scripts will be working with.
It's not unusual to start the planning of a major
scripting job by scoping out the data structures that will facilitate
DHTML-enhanced user interface features. When you do so, you will find
JavaScript arrays and custom objects to be the containers and
organizers of your data. These containers give your scripts a regular
way to access the data points and a clean way to structure the data
to make it easy to visualize the abstract comings and goings during
script execution.
3.0.1 JavaScript Arrays
The loose data typing that pervades
JavaScript
carries over to arrays, but even more so. Unlike similar structures
in many other programming languages, a JavaScript array is not
limited to a specific size chiseled in stone at the time of its
creation. You can add or delete items from an array at will. It is an
extraordinarily flexible data store.
Another feature of the JavaScript array is that each entry in the
array can hold data of any type. It's no problem
mixing strings, numbers, Booleans, and objects within the same array.
You can even change the data and data type for a single array entry
at any time. Neither of these practices may be advisable from a
programming-style point of view, but they're
possible nevertheless.
Arrays are indexed by zero-based integers. In other words, to
reference the first entry in an array named
myArray, use myArray[0]. A
reference to the array entry returns the entry's
value. To assign a value to an entry, use the simple assignment
(=) operator.
You may also use the add-by-value
(+=) operator to add a number or append a string
to an array entry, as appropriate.
The basic JavaScript array is a one-dimensional kind of array. But,
as you will see in Recipe 3.2 and Recipe 3.9, you can create more complex
array structures, including multidimensional arrays (arrays of
arrays), and arrays whose entries are complex custom objects.
3.0.2 JavaScript Custom Objects
The
"looseness" of the JavaScript
language, as exhibited in the way it handles data typing, arrays, and
variable values, extends to its concept of objects. Forget what you
know about object-oriented programming techniques and relationships
between objects. The notions of traditional classes, subclasses, and
message passing have little application in JavaScript (although some
of these ideas may come to the language in the future). Instead,
think of a custom object as simply a convenient container for data in
which the data values have labels that make it easier to remember
what's what. Custom object syntax is just like the
syntax you use for other JavaScript and DOM objects: it follows the
"dots"
rule (e.g.,
myObject.myProperty
and
myObject.myMethod(
)).
One of the hazards of bringing too much object-oriented programming
experience to scripting is that you might tend to turn every piece of
data into an object, even when the overhead (in terms of source code
space) to generate the object outweighs any functional or readability
benefit you might get from using objects. It's not
uncommon for an object-oriented approach to a simple problem to
obfuscate the relationships among data points. But if your scripts
frequently need to refer to some data associated with an entity that
hangs around in the global variable space, it probably makes good
sense to use an object there. In later chapters of this book, you
will see many objects used as repositories for bits of information
related to a particular item, such as the details of a drop-down
menu.
Despite the cautions expressed here about the difference between
objects in JavaScript (which are based on a concept called prototype
inheritance) and true object-oriented environments, you can simulate
a goodly amount of genuine OOP ideas with custom objects. Recipe 3.12
demonstrates a few of these simulations.
3.0.3 Choosing Between Arrays and Objects
So, when do you use
an array, and when do you use an object? Think of an
array as an ordered
list of similar kinds of data. The list, itself, signifies the
purpose or kind of data it contains, such as a series of coworker
names or the titles of all books on a shelf. The position of one item
among the others is not important, although you might like to sort
the list to, perhaps, show the contents in alphabetical order. Having
the items in this kind of "blind"
list means that at some point you will be looking through all items
in the list, perhaps to pull out their values for insertion into an
HTML element for display.
An object, on the
other hand, is best used to encapsulate information about a single
entity. A coworker object might contain properties
for the person's name and age; a book object could
have dozens of properties for information points such as title,
author, publisher, category, and so on. The properties are explicitly
named so that you can readily access the value of a single property
directly (e.g., book3.publisher). You can also
equip an object with methods whose actions operate on the object and
its properties (see Recipe 3.8).
As you will see in Recipe 3.7 and elsewhere, there is an advantage in
creating an array of objects. The
"array-ness" gives your scripts the
ability to iterate through the entire list of objects; the
"object-ness" lets the same script
inspect a specific property of each object in the array to perform
tasks like lookups. An array of book objects, for instance, lets a
looping construct look through the entire list of books and inspect
the author property of each item to accumulate the
title property values of those objects whose
author property meets a particular criterion.
Be prepared to use arrays and objects by themselves, as well as in
combination. Not only are you likely to use an array of
objects, but a property of an object may
be an array. For example, an object that represents a book might
define the author property as an array to accommodate multiple
authors. A book with a single author has a one-entry array for that
property, but the scripts that go diving for authors know to expect
an array data type there, as well as use appropriate comparison tools
against the entries in the array.
As dry as this chapter's subject may seem at first
glance, it may be the most important one in the entire book. Most of
the recipes from this chapter are used in later chapters repeatedly
because they are fundamental building blocks for a lot of Dynamic
HTML and other scripting.
3.0.4 Getting Data into the Page
Most of the recipes in this chapter show
data arrays and objects embedded directly within the page of the
examples. This approach works for a fixed set of data or, after the
page has loaded, data dynamically read from the page or user entry
forms. But you can also embed data from live sources—server
databases—with the help of server programming.
If you use a server environment (such as ASP, JSP, ColdFusion, PHP,
and many more) that assembles each page's content by
way of server-side templates and programs, you can use the same
environment to retrieve data from your databases and convert the
returned data sets into JavaScript arrays and objects to be delivered
with the rest of the page. Another approach is to let the external
script-loading capability of browsers (via the src
attribute of the <script> tag) point to a server process
URL. The URL contains query data that the
server program uses to fetch the database data, then the server
converts the returned data into JavaScript arrays and objects for
output to the client, delivered in the format and MIME type of a
.js file. The data becomes part of the
page's scripts, just as if it were directly embedded
in the page.
Even more elaborate schemes are possible. A hidden frame that
repeatedly queries the server can retrieve continually updated data
that comes back as JavaScript data-enhanced web pages. And hidden
Java applets can keep an open socket with a server process and
communicate the data to the page (in browsers that support
LiveConnect—Java-to-JavaScript—technology). All of these
approaches have the same goal: to embed data as JavaScript arrays
and/or objects for easy access and manipulation in a Dynamic HTML
client environment.
|