Team LiB   Previous Section   Next Section

8.6 Objects as Associative Arrays

We've seen the . operator used to access the properties of an object. It is also possible to use the [] operator, which is more commonly used with arrays, to access these properties. Thus, the following two JavaScript expressions have the same value:

object.property

object["property"] 

The important difference to note between these two syntaxes is that in the first, the property name is an identifier, and in the second, the property name is a string. We'll see why this is so important shortly.

In C, C++, Java, and similar strongly typed languages, an object can have only a fixed number of properties, and the names of these properties must be defined in advance. Since JavaScript is a loosely typed language, this rule does not apply -- a program can create any number of properties in any object. When you use the . operator to access a property of an object, however, the name of the property is expressed as an identifier. Identifiers must be typed literally into your JavaScript program -- they are not a data type, so they cannot be manipulated by the program.

On the other hand, when you access a property of an object with the [] array notation, the name of the property is expressed as a string. Strings are JavaScript data types, so they can be manipulated and created while a program is running. So, for example, you could write the following code in JavaScript:

var addr = "";

for(i = 0; i < 4; i++) {

    addr += customer["address" + i] + '\n';

} 

This code reads and concatenates the address0, address1, address2, and address3 properties of the customer object.

This brief example demonstrates the flexibility of using array notation to access properties of an object with string expressions. We could have written this example using the . notation, but there are cases where only the array notation will do. Suppose, for example, that you are writing a program that uses network resources to compute the current value of the user's stock market investments. The program allows the user to type in the name of each stock she owns, as well as the number of shares of each stock. You might use an object named portfolio to hold this information. The object has one property for each stock. The name of the property is the name of the stock and the property value is the number of shares of that stock. So, for example, if a user holds 50 shares of stock in IBM, the portfolio.ibm property has the value 50.

Part of this program needs to have a loop that prompts the user to enter the name of a stock she owns and then asks her to enter the number of shares she owns of that stock. Inside the loop, you'd have code something like this:

var stock_name = get_stock_name_from_user(  );

var shares = get_number_of_shares(  );

portfolio[stock_name] = shares; 

Since the user enters stock names at runtime, there is no way that you can know the property names ahead of time. Since you can't know the property names when you write the program, there is no way you can use the . operator to access the properties of the portfolio object. You can use the [] operator, however, because it uses a string value (which is dynamic and can change at runtime), rather than an identifier (which is static and must be hardcoded in the program), to name the property.

When an object is used this fashion, it is often called an associative array -- a data structure that allows you to dynamically associate arbitrary values with arbitrary strings. JavaScript objects are actually implemented internally as associative arrays. The . notation for accessing properties makes them seem like the static objects of C++ and Java, and they work perfectly well in that capacity. But they also have the powerful ability to associate values with arbitrary strings. In this respect, JavaScript objects are much more like Perl arrays than C++ or Java objects.

Chapter 6 introduced the for/in loop. The real power of this JavaScript statement becomes clear when we consider its use with associative arrays. To return to the stock portfolio example, we might use the following code after the user has entered her portfolio and we are computing its current total value:

var value = 0;

for (stock in portfolio) {  

    // For each stock in the portfolio, get the per share value  

    // and multiply it by the number of shares.

    value += get_share_value(stock) * portfolio[stock];

} 

We cannot write this code without the for/in loop because the names of the stocks aren't known in advance. This is the only way to extract those property names from the associative array (or JavaScript object) named portfolio.

    Team LiB   Previous Section   Next Section