Functions, Arrays, and Objects In JavaScript

In This Chapter

Making code manageable with functions
Passing parameters into functions
Returning values from functions
Examining functions and variable scope
Producing basic arrays
Retrieving data from arrays
Building a multi-dimensional array
Creating custom objects with properties and methods
Building object constructors
Building JSON data structures
It doesn’t take long for your code to become complex. Soon enough, you’ll find yourself wanting to write more sophisticated programs. When things get larger, you need new kinds of organizational structures to handle the added complexity.
You can bundle several lines of code into one container and give this new chunk of code a name. That’s called a function. You can also take a whole bunch of variables, put them into a container, and give it a name. That’s called an array.
This chapter shows you how to work with more code and more data — in the form of functions and arrays — without going crazy.

Breaking Code into Functions

It doesn’t take long for code to get complicated. It would be good to have some sort of tool for managing the complexity and making code easier to handle. That’s exactly what a concept called functions does for you.

Inviting ants to the picnic

To explain functions better, think back to an old campfire song. Figure 5-1 re-creates this classic song for you in JavaScript format. (You might want to roast a marshmallow while you view this program.)
Nothing reminds me of functions like a classic campfire song.
Figure 5-1:
Nothing reminds me of functions like a classic campfire song.
If you’re unfamiliar with this song, it simply recounts the story of a bunch of ants. The littlest one apparently has some sort of attention issues (but we love him anyway). During each verse, the little one gets distracted by something that rhymes with the verse number. The real song typically has ten verses, but I’m just doing two for the demo.


Thinking about song (and program) structure

Before you look at the code, think about the structure of the song. Like many songs, it has two main parts. The chorus is a phrase repeated many times throughout the song. The song has several verses, which are similar to each other, but not quite identical.
Think about the song sheet passed around the campfire. (I’m getting hungry for a s’more.) The chorus is usually listed only one time, and each verse is listed. Sometimes you’ll have a section somewhere on the song sheet that looks like this:
tmpB213_thumb_thumb
Musicians call this thing a “road map,” and that’s a great name for it. It’s a higher-level view of how you progress through the song. In the road map, you don’t worry about the details of the particular verse or chorus. The road map shows the big picture, and you can look at each verse or chorus for the details.

Building the antsFunction.html program

Take a look at the code for antsFunction.html and see how it resembles a song sheet:
tmpB214_thumb_thumbtmpB215_thumb_thumb

The program code breaks the parts of the song into the same pieces a song sheet does. Here are some interesting features of antsFunction.html:

I created a function called chorus(). Functions are simply collections of code lines with a name.
All the code for the chorus goes into this function. Anything I want to do as part of printing out the chorus goes into the chorus() function. Later, when I want to print the chorus, I can just call the chorus() function and it will execute all the code I stored there.
Each verse has a function, too. I broke the code for each verse into its own function as well.
The main code is a road map. After all the details are delegated to the functions, the main part of the code just controls the order in which the functions are called.
Details are hidden in the functions. The main code handles the big picture. The details (how to print the chorus or verses) are hidden inside the functions.
Functions are a very useful tool for controlling complexity. You can take a large, complicated program and break it into several smaller pieces. Each piece stands alone and solves a specific part of the overall problem.
You can think of each function as a miniature program. You can define variables in functions, put loops and branches in there, and do anything else you can do with a program. A program using functions is basically a program full of subprograms.
When you have your functions defined, they’re just like new JavaScript commands. In a sense, when you add functions, you’re adding your own new commands to JavaScript.

Passing Data into and out of Functions

Functions are logically separated from the main program. This is a good thing, because this separation prevents certain kinds of errors. Sometimes, however, you want to send information into a function. You might also want
a function to return some type of value. The antsParam.html page rewrites the “Ants” song in a way that takes advantage of function input and output:
tmpB216_thumb_thumb
I’m not providing a figure showing this program because it looks just like antsFunction.py to the user. That’s one of the advantages of functions: You can improve the underlying behavior of a program without imposing a change in the user’s experience. Here’s what the code looks like now:
tmpB217_thumb_thumb
There are a couple of important new ideas in this code (keep in mind that this is just the overview — specifics are coming in the next few sections):
These functions return a value. The functions don’t do their own alert statements any more. Instead, they create a value and return it to the main program.
There’s only one verse function. Because the verses are all pretty similar, it makes sense to have only one verse function. This improved function needs to know what verse it’s working on to handle the differences.

Examining the main code

The main code has been changed in one significant way. In the last program, the main code called the functions, which did all the work. This time, the functions don’t actually do the output themselves. Instead, they collect information and pass it back to the main program. Inside the main code, each function is treated like a variable.
You’ve seen this behavior before: The prompt() method returns a value. Now the chorus() and verse() methods also return values. You can do anything you want to this value, including printing it out or comparing it to some other value.
It’s often considered a good idea to separate the creation of data from its use as I’ve done here. That way you have more flexibility. After a function creates some information, you can print it to the screen, store it on a Web page, put it in a database, or whatever.

Looking at the chorus line

The chorus has been changed to return a value. Take another look at the chorus() function to see what I mean:
tmpB218_thumb_thumb

Here’s what changed:

The purpose of the function has changed. The function is no longer designed simply to output some value to the screen. Instead, it now provides text to the main program, which can do whatever it wants with the results.
There’s a variable called text. This variable will contain all the text to be sent to the main program. (This was true before, but it’s even more important now.)
The text variable is concatenated over several lines. I used string concatenation to build a complex value. Note the use of newlines (\n) to force carriage returns.
The return statement sends text back to the main program. When you want a function to return some value, simply use return followed by a value or variable. Note that return should be the last line of the function.

Handling the verses

The verse() function is quite interesting: To make the verse so versatile (get it? — VERSE-atile!), it must take input from the primary program and return output. It has these features:
It’s more flexible than the previous functions. The same function can be used to produce many different verses.
It takes input to determine which verse to print. The road map sends a verse number to the function.
It modifies the verse based on the input. The verse umber is used to determine how the rest of the verse should be created.
It returns a value, just as chorus() does. The output of this function is passed back to the main program so it can do something with the newly minted verse.

Passing data to the verse() function

First, notice that the verse() function is always called with a value inside the parentheses. For example, the main program says verse(1) to call the first verse, and verse(2) to invoke the second. The value inside the parentheses is called an argument.
The verse() function must be designed to accept an argument. Look at the first line and you’ll see how I did it:
tmpB219_thumb_thumb
I included a variable name, verseNum, in the function definition. Inside the function, this variable is known as a parameter. (Don’t get hung up on the terminology. People often use the terms “parameter” and “argument” interchangeably.) The important idea is this: Whenever the verse() function is called, it automatically has a variable called verseNum. Whatever argument you send to the verse() function from the main program will become the value of the variable verseNum inside the function.
You can define a function with as many parameters as you want. Each parameter gives you the opportunity to send a piece of information to the function.

Determining the distraction

If you know the verse number, you can determine what distracts “the little one” in the song. There are a couple of ways to do this, but a simple if / else if structure is sufficient for this example:
tmpB220_thumb_thumb
Here I initialized the variable distraction to be empty. If verseNum is 1, set distraction to “suck his thumb.” If verseNum is 2, distraction should be “tie his shoe”. Any other value for verseNum is treated as an error by the else clause.
If you’re an experienced coder, you might be yelling at the program. I know, it still isn’t optimal. Later in this chapter, I show an even better solution for handling this particular situation with arrays.
By the time this code segment is complete, there is a legitimate value for both verseNum and distraction.

Creating the text

After you know these variables (verseNum and distraction), it’s pretty easy to construct the output text:
tmpB221_thumb_thumb
There’s a whole lotta concatenatin’ going on, but it’s essentially the same code as the original verse() function. This one’s just a lot more flexible, because it can handle any verse. (Well, it can if the function has been preloaded to understand how to handle the particular verse number. More on that soon.)

Managing Scope

A function is much like an independent mini-program. Any variable you create inside a function only has meaning inside that function. When the function finishes executing, its variables disappear! This is actually a really good thing. A major program will have hundreds of variables. They can be very difficult to keep track of. It’s possible to re-use a variable name without knowing it, or have a value changed inadvertently. When you break your code into functions, each function has its own independent set of variables. You don’t have to worry about whether the variables will cause problems elsewhere.

Introducing local and global variables

You can also define variables at the main (script) level. These variables are considered global variables. A global variable is available at the main level and inside each function. A local variable (one defined inside a function) has meaning only inside the function. The concept of local-versus-global functions is sometimes referred to as scope.
Local variables are kind of like local police who have a limited geographical jurisdiction, but are very useful within that space. They know the neighborhood. Sometimes you’ll encounter situations that cross local jurisdictions. This is the kind of situation that requires a state trooper or the FBI. Local variables are local cops, and global variables are the FBI.
In general, try to make as many of your variables local as possible. The only time you really need a global variable is when you want some information to be used in multiple functions.

Examining variable scope

To understand the implications of variable scope, take a look at scope. html:
tmpB222_thumb_thumb
This program defines two variables. globalVar is defined in the main code, and localVar is defined inside a function. If you run the program in Debug mode while watching the variables, you can see how they behave. Figure 5-2 shows what the program looks like early in the run.
Note that localVar doesn’t have meaning until the function is called, so it remains undefined until the computer gets to that part of the code. Step ahead a few lines, and you’ll see localVar has a value, as shown in Figure 5-3.
Be sure to use the Step Into technique for walking through a program rather than Step Over for this example. When Step Over encounters a function, it runs the entire function as one line. If you want to look into the function and see what’s happening inside it (as you do here), use Step Into. Please look at Chapter 4 if you need a refresher on using debugging modes.
Here globalVar is defined, but localVar is not.
Figure 5-2:
Here globalVar is defined, but localVar is not.
Behold! localVar has a value — because I'm inside the function.
Figure 5-3:
Behold! localVar has a value — because I’m inside the function.
Note that globalVar still has a value — and so does localVar, because it’s inside the function.
If you move down the code a few more steps, you’ll find that localVar no longer has a value when the function ends. This is illustrated in Figure 5-4.
Variable scope is a good thing because it means you only have to keep track of global variables and the variables defined inside your current function. The other advantage of scope is that you can re-use a variable name. You can have ten different functions all using the same variable name and they won’t interfere with each other, because each one is an entirely different variable.
When the function ends, once again local-Var has no meaning.
Figure 5-4:
When the function ends, once again local-Var has no meaning.

Building a Basic Array

If a function is a group of code lines with a name, an array is similar; it’s a group of variables with a name. An array is actually a special kind of variable used to manage complexity. Use an array whenever you want to work with a list of similar data types.

Storing a list of data in an array

The following code shows a basic demonstration of arrays:

tmpB226_thumb_thumbtmpB227_thumb_thumb
The variable genre is a special variable, because it contains many different values. In essence, it is a list of game genres. The new Array(5) construct creates space in memory for five variables, all named genre.

Accessing array data

After you’ve specified an array, you can work with the individual elements using square brace syntax. Each element of the array is identified by an integer. The index usually begins with 0:
tmpB228_thumb_thumb
This line means: Assign the text value “flight simulation” to the genre array variable at position 0.
Most languages require that all array elements be the same type. JavaScript is very forgiving about this. You can combine all kinds of stuff in a JavaScript array. This can sometimes be very useful, but be aware this trick won’t work in all languages. In general, I try to keep all the members of an array the same type. Don’t forget that array indices usually start with 0.
After you’ve got the data stored in the array, you can use the same square-bracket syntax to read the information.
The line
tmpB229_thumb_thumb
means “find element 4 of the genre array, and include it in an output message.”
When genre.html is run, it shows what you see in Figure 5-5.
This data came from an array.
Figure 5-5:
This data came from an array.

Using arrays with for loops

The main reason to use arrays is for convenience. When you have a lot of information in an array, you can write code to work with the data quickly. Whenever you have an array of data, you commonly want to do something with each element in the array. Take a look at games.html to see how this can be done:
tmpB231_thumb_thumb

This code has some noteworthy things about it:

It features an array called gameList. This array contains the names of some of my favorite freeware games.
The array is pre-loaded with values. If you provide a list of values when creating an array, JavaScript simply pre-loads the array with the values you indicated. It isn’t necessary to specify the size of the array if you pre-load it.
A for loop steps through the array. Arrays and for loops are natural companions. The for loop steps through each element of the array.
The array’s length is used in the for loop condition. Rather than specifying the value 10, I used the length property of the array in my for loop. This is good, because the loop will automatically adjust to the size of the array if I add or remove elements.
It does something with each element. Because i goes from 0 to 9 (and these are they array indices), I can easily print out each value of the array. In this example, I simply add to an output string.
Note the newline characters. The \n combination is a special character. It tells JavaScript to add a carriage return (which is like pressing the Enter key).
When games.html runs, it looks like Figure 5-6.
If you want to completely ruin your productivity, you might want to Google some of these game names shown in Figure 5-6. They are absolutely incredible, and every one of them is free. It’s hard to beat that. (See, even if you don’t learn how to program in this topic, you get something good out of it!)
Now I've got a list of games. Arrays and loops are fun!
Figure 5-6:
Now I’ve got a list of games. Arrays and loops are fun!

Visiting the ants one more time

Just when you got that ant song out of your head, take a look at one more variation. This one uses arrays and loops to simplify the code even more!
tmpB233_thumb_thumbtmpB234_thumb_thumb
This code is just a little different from the antsParam program shown earlier.
It has an array called distractionList. This array is (despite the misleading name) a list of distractions. I made the first one (element 0) blank so the verse numbers would line up properly
The verse() function looks up a distraction. Because distractions are now in an array, the verseNum can be used as an index to loop up a particular distraction. Compare this function to the verse() function in antsParam. Although arrays require a little more planning than code structures, they can highly improve the readability of your code.
The main program is in a loop. I step through each element of the distractionList array, printing out the appropriate verse and chorus.
The chorus() function remains unchanged. There’s no need to change chorus() .

Working with Two-Dimensional Arrays

Arrays are useful when working with lists of data. Sometimes you’ll encounter data that’s best imagined in a table. For example, consider if you wanted to build a distance calculator that determines the distance between two cities. The original data might look like Table 5-1.

Table 5-1 Distances between Major Cities
0) Indianapolis 1) New York 2) Tokyo 3) London
0) Indianapolis 0 648 6476 4000
1) New York 648 0 6760 3470
2) Tokyo 6476 6760 0 5956
3) London 4000 3470 5956 0

Think about how you would use this table to figure out a distance. If you wanted to travel from New York to London, for example, you’d pick out the New York row and the London column and figure out where they intersect. The data in that cell is the distance (3,470 miles).
When you look up information in any kind of a table you’re actually working with a two-dimensional data structure. That’s a fancy term, but it just means “table.” If you want to look something up in a table, you need two indices, one to determine the row, and another to determine the column.
If this is difficult to grasp, think of the old game “Battleship.” The playing field is a grid of squares. You announce “I-5″ (meaning “column I, row 5″) and your opponent looks in that grid to discover that you’ve sunk his battleship. In programming, typically you use integers for both indices, but otherwise it’s exactly the same: Any time you have two-dimensional data, you access it with two indices.
Often we call these indices row and column to help you think of the structure as a table. Sometimes there are better names that more clearly describe how the behavior works. Take a look at Figure 5-7 and you’ll see that the distance.html program asks for two cities and returns a distance according to the data table.
Yep, it’s possible to have 3-, 4-, and n-dimension arrays in programming, but don’t worry about that yet. (It might make your head explode.) Most of the time, 1 or 2 dimensions are all you need.
It's a "Tale of Two Cities." You even get the distance between them!
Figure 5-7:
It’s a “Tale of Two Cities.” You even get the distance between them!
This program is a touch longer than some of the others, so I break it into parts for easy digestion. Be sure to look at the program in its entirety on either of the companion.

Setting up the arrays

The key to this program is the data organization. The first step is to set up two arrays, and it looks like this:
tmpB236_thumb_thumb
The first array is an ordinary single-dimension array of city names. I’ve been careful to always keep the cities in the same order, so whenever I refer to city 0, I’m talking about Indianapolis (my home town.) New York is always going to be at position 1, and so on.
In your data design, take care that you always keep things in the same order. Be sure to organize your data on paper before you type it into the computer, so you’ll understand what value goes where.
The cityNames array has two jobs. First, it reminds me what order all the cities will be in, and secondly, it gives me an easy way to get a city name when I know an index. For example, I know that cityName[2] will always be “Tokyo.”
The distance array is very interesting. If you squint at it a little bit, it looks a lot like Table 5-1. That’s because it is Table 5-1, just in a slightly different format.
Keep in mind that distance is an array. JavaScript arrays can hold just about everything, including other arrays! That’s what distance does: It holds an array of rows. Each element of the distance array is another (unnamed) array holding all the data for that row. If you want to extract information from the array, you need two pieces of information. First you need the row. Then, because the row is an array, you need the column number within that array. So distance[1][3] means. “Go to row one (New York) of the array named distance. Within that row, go to element 3 (London) and return the resulting value (3 47 0).” Cool, huh?

Getting a city

The program requires that you ask for two cities. You want the user to enter a city number, not a name, and you want to do this twice. This sounds like a good time for a function:
tmpB237_thumb_thumb
Here the getcity() function prints up a little menu of city choices, and asks for some input. It then returns that input.
There’s all kinds of ways to improve getcity() . For one thing, maybe it should repeat until you get a valid number, so that users can’t type in the city name or do something else crazy. I’ll leave it simple for now. The next chapter shows you how to use the elements of a user interface to help the user submit only valid input.

Creating a main() function

The main() function handles most of the code for the program. Here’s what that looks like:
tmpB238_thumb_thumb

In this code, the main() function controls traffic. Here’s how it works:

1. Create an output variable.
The point of this function is to create some text output describing the distance. I begin by creating a variable called output and setting its initial value to empty.
2. Get the city of origin.
Fortunately, you’ve got a really great function called getcity() that handles all the details of getting a city in the right format. Call this function and assign its value to the new variable from.
3. Get the destination city.
That getcity() function sure is handy. Use it again to get the city number you’ll call to.
4. Get the distance.
Because you know two indices, and you know they’re in the right format, you can simply look them up in the table. Look up distance[from] [to] and store it in the variable result.
5. Output the response.
Use concatenation to build a suitable response string and send it to the user.
6. Get city names from the cityNames array.
The program uses numeric indices for the cities, but these don’t mean anything to the user. Use the cityNames array to retrieve the two city names for the output.
7. Run the main() function.
There’s only one line of code that’s not in a function. That line calls the main() function and starts the whole thing up.
I didn’t actually write the program in the order in which I showed it to you. Sometimes it makes more sense to go “inside out” with your programming, and that was the case here: I actually created the data structure first (as an ordinary table on paper) and then constructed the main() function. This made it obvious that I needed a getcity() function, and gave me some clues about how getcity should work (that is, it should present a list of cities and then prompt for a numerical input).

Creating Your Own Objects

So far, you’ve used a lot of wonderful objects in JavaScript — but that’s just the beginning. It turns out you can build your own objects too, and these objects can be very powerful and flexible. Objects typically have two important components: properties and methods. A property is like a variable associated with an object. It describes the object. A method is like a function associated with an object. It describes things the object can do.
Functions allow you to put code segments together; arrays allow you to put variables together; objects allow you to put both code segments and variables (and in fact functions and arrays) in the same large construct.

Building a basic object

JavaScript makes it trivially easy to build an object. Because a variable can contain any value, you can simply start treating a variable like an object and it becomes one.
Figure 5-8 shows a critter that has a property.
This alert box is actually using an object.
Figure 5-8:
This alert box is actually using an object.

Take a look at the following code:

tmpB240_thumb_thumb

The way it works is not difficult to follow:

1. Create a new object.
JavaScript has a built-in object called Object. Make a variable with the new Object() syntax, and you’ll build yourself a shiny new standard object.
2. Add properties to the object.
A property is like a subvariable. It’s nothing more than a variable attached to a specific object. When you assign a value to critter, name, for example, you’re specifying that critter has a property called name and you’re also giving it a starting value.
3. An object can have any number of properties.
Just keep adding properties. This allows you to group a number of variables into one larger object.
4. Each property can contain any type of data.
Unlike arrays — in which it’s common for all the elements to contain exactly the same type of data — each property can have a different type.
5. Use the dot syntax to view or change a property.
If the critter object has a name property, you can use critter. name as a variable. Like other variables, you can change the value by assigning a new value to city.name or you can read the content of the property.
If you’re used to a stricter object-oriented language like Java, you’ll find JavaScript’s easy-going attitude quite strange and maybe a bit sloppy. Other languages do have a lot more rules about how objects are made and used, but JavaScript’s approach does have its charms. Don’t get too tied up in the differences. The way JavaScript handles objects is powerful and refreshing.

Adding methods to an object

Objects have other characteristics besides properties. They can also have methods. A method is simply a function attached to an object. To see what I’m talking about, take a look at this example:
tmpB241_thumb_thumb
This example extends the critter object described in the last section. In addition to properties, the new critter has a talk() method. If a property describes a characteristic of an object, a method describes something the object can do. Figure 5-9 illustrates the critter showing off its talk() method.
Now the critter can talk!
Figure 5-9:
Now the critter can talk!

Here’s how it works:

1. Build an object with whatever properties you need.
Begin by building an object and giving it some properties.
2. Define a method much like a property.
In fact, methods are properties in JavaScript, but don’t worry too much about that — it’ll make your head explode.
3. You can assign a pre-built function to a method.
If you’ve already created a function that you want to use as a method, you can simply assign it.
4. You can also create an anonymous function.
More often, you’ll want to create your method right away. You can create a function immediately with the function(){ syntax.
5. The this keyword refers to the current object.
Inside the function, you might want to access the properties of the object. this.name refers to the name property of the current object.
6. You can then refer to the method directly.
After you’ve defined an object with a method, you can invoke it. For example, if the critter object has a talk() method, use critter. talk() to invoke this method.

Building a re-usable object

These objects are nice, but what if you want to build several objects with the same definition? JavaScript supports an idea called a constructor, which allows you to define an object pattern and re-use it.

Here’s an example:

tmpB243_thumb_thumbtmpB244_thumb_thumb
This example involves creating a class (a pattern for generating objects) and re-using that definition to build two different critters. First, look over how the class definition works:
1. Build an ordinary function.
JavaScript classes are defined as extensions of a function. The function name will also be the class name. Note that the name of a class function normally begins with an uppercase letter. When a function is used in this way to describe an object, the function is called the object’s constructor. The constructor can take parameters if you wish, but it normally does not return any values. In my particular example, I add parameters for name and age.
2. Use this to define properties.
Add any properties you want, including default values. Note that you’ll be able to change those values later if you like. Each property should begin with this and a period, so if you want your object to have a color property, you’d say something like this.color = “blue”;. My example uses the local parameters to define the properties. This is a very common practice, because it’s an easy way to pre-load important properties.
3. Use this to define any methods you want.
If you want your object to have methods, define them using the this operator followed by the function(){ keyword. You can add as many functions as you want.
The way JavaScript defines and uses objects is easy but a little nonstandard. Most other languages that support object-oriented programming do it in a different way than the technique described here. Some would argue that JavaScript is not a true OOP language, as it doesn’t support a feature called inheritance, but instead uses a feature called prototyping. The difference isn’t all that critical; most uses of OOP in JavaScript are very simple objects like the ones described here or JSON, described later in this chapter. Just appreciate that the introduction to object-oriented programming here is very cursory, but enough to get you started.

Using your shiny new objects

When you’ve defined a class, you can re-use it. Look again at the main function to see how I use my newly minted Critter class:
tmpB245_thumb_thumb
After a class is defined, you can use it as a new data type. This is a very powerful capability. Here’s how it works:
1. Be sure you have access to the class.
A class isn’t useful unless JavaScript already knows about it. In this example, the class is defined within the code.
2. Create an instance of the class with the new keyword.
The new keyword means you want to make a particular critter based on the definition. Normally you’ll assign this to a variable. My constructor expects the name and age to be supplied, so it automatically creates a critter with the given name and age.
3. Modify the class properties as you want.
You can change the values of any of the class properties. In my example, I change the name and age of the second critter just to show how it’s done.
4. Call class methods.
Because the Critter class has a talk() method, you can use it whenever you want a particular critter to talk.

Introducing JSON

JavaScript objects and arrays are incredibly flexible. In fact, they are so well-known for their power and ease of use, that a special data format called JSON (JavaScript Object Notation) has now been adopted by many other languages.
JSON is mainly used as a way to store complex data (especially multi-dimension arrays) and pass the data from program to program. JSON is essentially another way of describing complex data in a JavaScript Object format. When you describe data in JSON, you generally do not need a constructor, because the data itself is used to determine the structure of the class.
JSON data is becoming a very important part of Web programming, because it allows an easy mechanism for transporting data between programs and programming languages. Throughout this topic (especially in the sections on AJAX and the jQuery library), you’ll see JSON used extensively to manage complex data easily.

Storing data in JSON format

To see how JSON works, begin by looking at this simple code fragment:

tmpB246_thumb_thumb
This code describes a critter with two properties, a name and an age. The critter looks much like an array, but rather than using a numeric index (as most arrays do), the critter has string values to serve as indices. It is, in fact, an object.
You can refer to the individual elements with a variation of array syntax, like
this:
tmpB247_thumb_thumb
You can also use what’s called dot notation (as used in objects,) like this:
tmpB248_thumb_thumb
Both notations work in the same way. Most of the built-in JavaScript objects use the dot notation, but either is acceptable.
The reason JavaScript arrays are so useful is that they are in fact objects. When you create an array in JavaScript, you are building an object with numerical property names. This is why you can use either array or object syntax for managing JSON object properties.
Look at jsonDistance.html  to see the code from this section in action. I don’t show a figure here, because all the interesting work happens in the code.

Here’s how to store data in JSON notation:

1. Create the variable.
You can use the var statement like you do any variable.
2. Contain the content within braces({}).
This is the same mechanism you use to create a pre-loaded array (as described earlier in this chapter).
3. Designate a key.
For the critter, I want the properties to be named “name” and “age” — that is, with words rather than numeric indices. For each property, I begin with the property name. The key can be a string or an integer.
4. Follow the key with a colon (:).
The key is followed by the colon character.
5. Create the value associated with that key.
You can then associate any type of value you want with the key. In this case, I associate the value “George” with the key “name”.
6. Separate each name/value pair with a comma (,).
You can add as many name/value pairs as you want.
If you’re familiar with other programming languages, you might think of a JSON structure as being like a hash table or associative array. JavaScript does use JSON structures in the same way these other structures are used, but it isn’t quite accurate to say JSON is either a hash or an associative array. It’s simply an object. (But if you want to think of it as one of those things, I won’t tell anybody.)

Building a more complex JSON structure

JSON is convenient because it can be used to handle quite complex data structures. For example, look at the following (oddly familiar) data structure written in JSON format:
tmpB249_thumb_thumb
This data structure is another way of representing the distance data used to describe two-dimension arrays. This is another two-dimension array, but it is a little different than the one previously described.
distance is a JSON object. The entire data structure is stored in a single variable. This variable is a JSON object with name/value pairs.
The distance object has four keys. These correspond to the four rows of the original chart.
The keys are actual city names. The original 2D array used numeric indices, which are convenient but a bit artificial. In the JSON structure, the indices are the actual city names.
The value of each entry is another JSON object. The value of a JSON element can be anything, including another JSON object. Very complex relationships can be summarized in a single variable.
Each row is summarized as a JSON object. For example, the value associated with “Indianapolis” is a list of distances from Indianapolis to the various cities.
The entire declaration is one “line” of code. Although placed on several lines in the editor (for clarity), the entire definition is really just one line of code.
Setting up the data in this way seems a bit tedious, but it’s very easy to work with. The city names are used directly to extract data, so you can find the distance between two cities with array-like syntax:
tmpB250_thumb_thumb
If you prefer, you can use the dot syntax:
tmpB251_thumb_thumb
You can even go with some kind of hybrid:
tmpB252_thumb_thumb

JSON has a number of important advantages as a data format:

‘ It is self-documenting. Even if you see the data structure on its own without any code around it, you can tell what it means.
The use of strings as indices makes the code more readable. It’s much
easier to understand distance["Indianapolis"]["London"] than to decipher distance[0][3] .
‘JSON data can be stored and transported as text. This turns out to have profound implications for Web programming, especially in AJAX (the techniques described elsewhere in this topic).
JSON can describe complex relationships. The example shown here is a simple two-dimension array, but the JSON format can be used to describe much more complex relationships — including complete databases.
Many languages support JSON format. Many Web languages now offer direct support for JSON. The most important of these is PHP, which is very frequently used with JavaScript in AJAX applications.
‘ JSON is more compact than XML. Another data format called XML is frequently used to transmit complex data. However, JSON is more compact and less “wordy” than XML.
JavaScript can read JSON natively. Some kinds of must be translated before they can be used. As soon as your JavaScript program has access to JSON data, it can be used directly.
You might wonder whether you can embed methods in JSON objects. The answer is yes, but this isn’t usually done when you’re using JSON to transport information. In Part III of this topic about AJAX, you’ll see that methods are often added to JSON objects to serve as callback functions, but that usage won’t make sense until you get more familiar with events. To get a start on that, flip to Chapter 14.

Next post:

Previous post: