Chapter 1. Representing Data with Values

When you walk into my childhood home in Pittsburgh, it's evident a fellow with a lively mind lives there. Photos from trips to some thirty-one countries on six continents line the walls. Intermingling those are Aborigine and Aleut art, prints by Klimt and Degas, tapestries from Egypt and Peru, and Greek sculptures. Notable literary works fill the library.

Though conversations with my dad are interesting, they tend to be interspersed with what my mom would call "the comment from nowhere," an unpredicated excerpt from whatever he is thinking about. For example, I was over there for a Steelers game on a damp November day. I think they were playing the Ravens, their blood rival. So, the carnage was fairly medieval. Moreover, Heinz Field was a mess. It was more like a muddy cow pasture than a football field.

On a third and long with the Steelers nearly within field goal range, Roethlisberger dropped back to pass. But Hines Ward, his intended receiver, slipped and fell on a timing pattern, sprawling face down in the mud. So, the ball sailed over the first down marker, incomplete.

As the Steelers prepared to punt, I probably muttered something unprintable. Dad, on the other hand, peered at me overtop his reading glasses and queried, "Did you know that the French may have lost to the English at Agincourt due to the depth of the mud?" Though I didn't say, "No, and why are you telling me that?" I sure was thinking it.

If you are new to JavaScript and programming, some of the things I say in the first few chapters may bewilder you like Dad's query did me. Just know that, although I've been hand-coding JavaScript for 12 years, I've not forgotten how tough it can be at the very beginning. So, this book is written conversational style, covering only things that matter.

It's kind of like the knee-deep mud in a rain-soaked, newly plowed field bordering the woods of Agincourt did on October 25, 1415. That proved very tiring for French knights to wade through wearing some 50 to 60 pounds of full-plate armor. Those who later fell in the deep mud during the mêlée had difficulty regaining their feet, leaving them still targets for English longbowmen. Some trampled French knights even drowned in their armor. Within a few hours, the French army had been crushed by an English army one-fifth its size. Historians put the French dead at 10,000 compared to 112 for the English, attributing the slaughter to the muddy terrain.

Dad told me those details over dinner following the game, noting that he had been prepping a lecture on Henry V, a Shakespeare play featuring the battle of Agincourt, for a course he was giving at Penn State University. So, the comment from nowhere came from somewhere, too!

So, hang in there during early going while the mud is deep. Things will fall into place for you later in the book just like they did for me later in the day.

What Are Value Types?

In JavaScript, data is represented with values. There are four value types to convey data with: string, number, boolean, and object. Additionally, there are two value types to convey no data with: undefined and null. Two ways to convey "nothing there" won't seem so strange in Chapter 3.

The simplest way to create a string, number, boolean, or object value in JavaScript is to literally type it into your script. Doing so creates a literal value, or, more plainly, a literal.

Creating a String Literal

Plain text like my favorite ice cream, Ben & Jerry's Chocolate Fudge Brownie, is represented with a string value in JavaScript. Just wrap some text in a pair of double or single quotation marks, and you have yourself a string.

Alright, open firebug.html in Firefox, and then press F12 to enable Firebug. If you're just joining us, flip back to the Preface for details on how to do this. Type the following string in the right panel of Firebug, and click Run. As Figure 1-1 displays, JavaScript will echo the string value, printing it in the left panel of Firebug:

"Ben & Jerry's Chocolate Fudge Brownie";
JavaScript parrots the string literal back to us.

Figure 1-1. JavaScript parrots the string literal back to us.

JavaScript interpreters for Firefox and other browsers return a string value in double quotes. So, we'll go with double quotes in this book. But it doesn't matter. The only thing I would say is choose one style or the other and stick with it.

Note that the previous string is followed by a semicolon. Every statement, which is simply something you tell JavaScript to do, ends with a semicolon. Our simple statement shown earlier tells JavaScript to create a string literal in memory. We'll explore statements more fully in Chapter 4.

Commenting Code

Just like CSS or XHTML, JavaScript permits you to comment your code and format it with whitespace. Single-line comments begin with a //. JavaScript disregards anything following the // until the end of the line. In this book, code samples I want you to enter and run are followed by a comment listing the return value JavaScript will print in Firebug. So, to let you know JavaScript will echo the string literals, I'd write this:

"Ben & Jerry's";
// "Ben & Jerry's"
"Chocolate Fudge Brownie";
// "Chocolate Fudge Brownie"

But you would just enter and run the following:

"Ben & Jerry's";
"Chocolate Fudge Brownie";

If a code sample has two or more comments, that is your clue to stop and click Run to verify a return value before keying in the remainder of the sample.

Gluing Strings Together with the + Operator

To glue two strings together, separate them with the + concatenation operator. We'll explore + and a slew of other operators, listed here, in Chapter 3. Note that the values you give an operator to work with are referred to as operands.

[]
.
()
new
++
--
!
delete
typeof
void
*
/
%
+
-
<
<=
>
>=
instanceof
in
===
!===
==
!=
&&
||
?:
=
*=
/=
%=
+=
-=
,

Click Clear in both Firebug panels, and then cobble together a larger string from five smaller ones.

"Ben & Jerry's" + " " + "Chocolate Fudge Brownie" + " is my favorite icecream.";
// "Ben &  Jerry's Chocolate Fudge Brownie is my favorite icecream."

Verify your work with Figure 1-2.

Gluing five strings together with the + operator

Figure 1-2. Gluing five strings together with the + operator

Note that "Ben & Jerry's" + " " + "Chocolate Fudge Brownie" + " is my favorite icecream." is referred to as an expression for a value. In JavaScript, those are any phrases of code that create a value. You might think of an expression as a recipe for a value. We'll explore that analogy in Chapter 3.

Creating a Number Literal

Scripts typically do a lot of math. So, JavaScript, of course, has a number value type. Click Clear in Firebug, and let's have JavaScript do some math.

Chocolate Fudge Brownie has 4 servings per pint and 260 calories per serving. So, we could have JavaScript calculate the calories per pint with the * operator, which multiplies its operands:

4 * 260;
// 1040

I'm an avid runner, taking daily runs of some 14 miles Monday through Saturday. On Sundays I go for 21. We could have JavaScript calculate yearly miles with the following expression. Note that / does division and + does addition. Note too that JavaScript evaluates anything in parentheses first.

(6 * 14 + 21) / 7 * 365;
// 5475

It takes roughly 100 calories to run a mile, so, if I were to fuel my running entirely with Chocolate Fudge Brownie, how many pints would I need per year? Note that Math.round() rounds a decimal number to an integer. So, in our case, it rounds 526.4423076923077 to 526. Math.round() is one of the features for manipulating numbers that we'll explore in Chapter 5. Note too that + does addition if both its operands are numbers but concatenation if either operand is a string. For that to work, JavaScript converts the number 526 to the string "526" before gluing it to "pints of Chocolate Fudge Brownie". Verify your work with Figure 1-3.

Math.round((6 * 14 + 21) / 7 * 365 * 100 / (4 * 260)) + " pints of Chocolate Fudge Brownie";
// "526 pints of Chocolate Fudge Brownie"

I think I'll stay with an organic, whole-foods diet for now. But, if I'm still running when I'm 90, maybe I'll give that a try!

Doing some math with numbers

Figure 1-3. Doing some math with numbers

Note

JavaScript's value type conversion feature is covered more fully in Chapter 2.

Creating a Boolean Literal

Sometimes you will want a simple yes or no answer from JavaScript. In those circumstances, the return value for an expression will be true for yes and false for no.

Click Clear in both Firebug panels, and let's ask JavaScript whether Chocolate Fudge Brownie is just chocolate ice cream. Note that the === operator tells you whether two values are identical:

"Chocolate Fudge Brownie" === "chocolate icecream";
// false

That's an understatement. Alright, now let's compare the previous calculation to its return value, before verifying our work with Figure 1-4:

Math.round((6 * 14 + 21) / 7 * 365 * 100 / (4 * 260)) + " pints of Chocolate Fudge Brownie"
===
  "526 pints of Chocolate Fudge Brownie";
// true
The === operator always returns a boolean.

Figure 1-4. The === operator always returns a boolean.

Note

Comparison operators such as === all return booleans. Moreover, JavaScript can convert any string, number, object, null, or undefined value to a boolean. We'll explore value type conversion in Chapter 2. For those reasons, booleans are vital for controlling flow, something we'll explore in Chapter 4.

Naming a Value with an Identifier

Insofar as the literals we have created thus far are anonymous, we have no way to query or manipulate their values later. To fix this, we need to name them with an identifier. Doing so creates a variable, which of course is a named value.

OK, click Clear in both Firebug panels. Then type the keyword var followed by the identifier iceCream and a semicolon. Doing so declares a variable named iceCream to JavaScript. However, iceCream contains undefined, a literal conveying no value.

var iceCream;

Let's put the string literal "Chocolate Fudge Brownie" in iceCream with the = operator:

var iceCream;
iceCream = "Chocolate Fudge Brownie";

To query the value contained by a variable, type its identifier. Type iceCream, and click Run. JavaScript will then return the string literal:

var iceCream;
iceCream = "Chocolate Fudge Brownie";
iceCream;
// "Chocolate Fudge Brownie"

To put a new value in iceCream, do another = operation. So, let's replace "Chocolate Fudge Brownie" with "New York Super Fudge Chunk" like so:

var iceCream;
iceCream = "Chocolate Fudge Brownie";
iceCream = "New York Super Fudge Chunk";
iceCream;
// "New York Super Fudge Chunk"

Can I Name a Variable Anything I Want?

Sorry, no. JavaScript identifiers may only contain letters, numbers, and the _ underscore character. It can't begin with a number, though. Insofar as identifiers may not contain whitespace, ones containing two or more words are written in camel case. That is to say, spaces are deleted, and the first letter in every word but the first is capitalized. So, newYorkSuperFudgeChunk is camel case for "New York Super Fudge Chunk".

Though you may not name a variable anything you want, you may put any expression in it. So, you're not limited to literals. Click Clear in both Firebug panels, and then enter and run the following, before verifying this and the previous few samples with Figure 1-5.

var newYorkSuperFudgeChunk = 4 * 300 + " calories per pint";
newYorkSuperFudgeChunk;
// "1200 calories per pint"
Creating validly named variables

Figure 1-5. Creating validly named variables

The reason this works is that = has very low precedence compared to * and +. In Chapter 3, we'll explore precedence, which determines the pecking order of operators more fully.

Some Valid Identifiers Are Already Taken

JavaScript syntax, as defined by the ECMAScript standard, reserves the following identifiers, referred to as keywords. Those are JavaScript's key to do something for you. So, the term is apt. Naming a variable with a keyword returns a syntax error:

break
case
catch
continue
default
delete
do
else
finally
for
function
if
in
instanceof
new
return
switch
this
throw
try
typeof
var
void
while
with

By the end of this book, you will know what all these keywords tell JavaScript to do. So, by then, it will be obvious not to name a variable with a keyword.

On the other hand, future versions of ECMAScript may add the following keywords. Those still won't mean anything to you by the end of the book. But don't feel bad; they still don't mean anything to JavaScript either. Anyway, don't name a variable with one of the following reserved words:

abstract
boolean
byte
char
class
const
debugger
double
enum
export
extends
final
float
goto
implements
import
int
interface
long
native
package
private
protected
public
short
static
super
synchronized
throws
transient
volatile

In addition to keywords and reserved words, JavaScript has some predefined variables, too. So, the following identifiers are already taken:

arguments
Array
Boolean
Date
decodeURI
decodeURIComponent
encodeURI
Error
escape
eval
EvalError
Function
Infinity
isFinite
isNaN
Math
NaN
Number
Object
parseFloat
parseInt
RangeError
ReferenceError
RegExp
String
SyntaxError
TypeError
undefined
unescape
URIError

Note

If you are curious about the ECMAScript standard, visit http://www.ecmascript.org.

Creating an Object Literal

The object value type provides a way for you to create a place in memory for related values, which may be named with an identifier or string. Those related values are referred to as members. So, we say an object contains members.

Alright, click Clear in both Firebug panels. Then create an empty object literal named iceCream by keying in a pair of curly braces, followed of course by a semicolon.

var iceCream = {
};

Now add a member named "Chocolate Fudge Brownie" followed by an expression with the number of calories per pint. Just like variables, members may contain a literal value or an expression for a value. Note that the name of the member is separated from the value by a colon.

var iceCream = {
  "Chocolate Fudge Brownie": 4 * 260
};

OK, now members are separated by a comma. So to add a second member, follow the first one with a comma, like so:

var iceCream = {
  "Chocolate Fudge Brownie": 4 * 260,
  "Half Baked": 4 * 250
};

Now there are several more members so that we have ten in all. Just remember to separate them with a comma. But don't follow the final member—"Mission to Marzipan"—with a comma.

var iceCream = {
  "Chocolate Fudge Brownie": 4 * 260,
  "Half Baked": 4 * 250,
  "New York Super Fudge Chunk": 4 * 300,
  "Coffee Heath Bar Crunch": 4 * 280,
  "Cherry Garcia": 4 * 240,
  "Mud Pie": 4 * 270,
  "Milk & Cookies": 4 * 270,
  "Cinnamon Buns": 4 * 290,
  "Chocolate Chip Cookie Dough": 4 * 270,
  "Mission to Marzipan": 4 * 260
};

To query a member in iceCream, type iceCream, and then put the member name within the [] operator. Let's query "Chocolate Fudge Brownie", my favorite Ben & Jerry's, then verify our work with Figure 1-6.

var iceCream = {
  "Chocolate Fudge Brownie": 4 * 260,
  "Half Baked": 4 * 250,
  "New York Super Fudge Chunk": 4 * 300,
  "Coffee Heath Bar Crunch": 4 * 280,
  "Cherry Garcia": 4 * 240,
  "Mud Pie": 4 * 270,
  "Milk & Cookies": 4 * 270,
  "Cinnamon Buns": 4 * 290,
  "Chocolate Chip Cookie Dough": 4 * 270,
  "Mission to Marzipan": 4 * 260
};
iceCream["Chocolate Fudge Brownie"] + " calories per pint";
// "1040 calories per pint"
Querying a member in iceCream

Figure 1-6. Querying a member in iceCream

Hmm. It think I mismarked "Half Baked". It ought to be 270 per serving, not 250. So, how would we write a new value to the "Half Baked" member?

Yup, with the = operator. Writing a member is like writing a variable. Let's do so in Firebug, verifying our work with Figure 1-7:

var iceCream = {
  "Chocolate Fudge Brownie": 4 * 260,
  "Half Baked": 4 * 250,
  "New York Super Fudge Chunk": 4 * 300,
  "Coffee Heath Bar Crunch": 4 * 280,
  "Cherry Garcia": 4 * 240,
  "Mud Pie": 4 * 270,
  "Milk & Cookies": 4 * 270,
  "Cinnamon Buns": 4 * 290,
  "Chocolate Chip Cookie Dough": 4 * 270,
  "Mission to Marzipan": 4 * 260
};
iceCream["Half Baked"] = 4 * 270;
iceCream["Half Baked"] + " calories per pint";
// "1080 calories per pint"
Writing a new value to a member

Figure 1-7. Writing a new value to a member

Now what if I want to add a new flavor, say "Peanut Butter Cup" to iceCream? That works the same way as changing the value of a member. So, = changes the value of a member or adds a new one. It just depends on whether the member you query is defined already.

In Firebug, let's add a member named "Peanut Butter Cup" like so. Then query its value, verifying our work with Figure 1-8:

var iceCream = {
  "Chocolate Fudge Brownie": 4 * 260,
  "Half Baked": 4 * 270,
  "New York Super Fudge Chunk": 4 * 300,
  "Coffee Heath Bar Crunch": 4 * 280,
  "Cherry Garcia": 4 * 240,
  "Mud Pie": 4 * 270,
  "Milk & Cookies": 4 * 270,
  "Cinnamon Buns": 4 * 290,
"Chocolate Chip Cookie Dough": 4 * 270,
  "Mission to Marzipan": 4 * 260
};
iceCream["Peanut Butter Cup"] = 4 * 360;
iceCream["Peanut Butter Cup"] + " calories per pint";
// "1440 calories per pint"
Adding a new member to an object

Figure 1-8. Adding a new member to an object

Yipes, 1440 calories! On second thoughts, I'd like to remove that from iceCream. To do so, pass the "Peanut Butter Cup" member to the delete operator, which as its name implies deletes a member from an object. Consequently, when we query iceCream["Peanut Butter Cup"] following its demolition, JavaScript returns undefined to convey no value. We can't glue undefined to a string, though. So, JavaScript converts it to "undefined" first.

var iceCream = {
  "Chocolate Fudge Brownie": 4 * 260,
  "Half Baked": 4 * 270,
  "New York Super Fudge Chunk": 4 * 300,
  "Coffee Heath Bar Crunch": 4 * 280,
  "Cherry Garcia": 4 * 240,
  "Mud Pie": 4 * 270,
  "Milk & Cookies": 4 * 270,
  "Cinnamon Buns": 4 * 290,
  "Chocolate Chip Cookie Dough": 4 * 270,
  "Mission to Marzipan": 4 * 260
};
iceCream["Peanut Butter Cup"] = 4 * 360;
delete iceCream["Peanut Butter Cup"];
iceCream["Peanut Butter Cup"] + " calories per pint";
// "undefined calories per pint"

Naming Members with Identifiers

Naming iceCream members with strings enabled us to use whitespace, which is forbidden for identifiers. But we could have gone with camel case identifiers like so:

var iceCream = {
  chocolateFudgeBrownie: 4 * 260,
  halfBaked: 4 * 270,
  newYorkSuperFudgeChunk: 4 * 300,
  coffeeHeathBarCrunch: 4 * 280,
  cherryGarcia: 4 * 240,
  mudPie: 4 * 270,
  milkCookies: 4 * 270,
  cinnamonBuns: 4 * 290,
  chocolateChipCookieDough: 4 * 270,
  missionToMarzipan: 4 * 260
};

Having done so, we can now query members with the . operator followed by an identifier. Try doing so in Firebug by entering and running the following sample, verifying your work with Figure 1-9.

var iceCream = {
  chocolateFudgeBrownie: 4 * 260,
  halfBaked: 4 * 270,
  newYorkSuperFudgeChunk: 4 * 300,
  coffeeHeathBarCrunch: 4 * 280,
  cherryGarcia: 4 * 240,
  mudPie: 4 * 270,
  milkCookies: 4 * 270,
  cinnamonBuns: 4 * 290,
  chocolateChipCookieDough: 4 * 270,
  missionToMarzipan: 4 * 260
};
iceCream.newYorkSuperFudgeChunk + " calories per pint";
// "1200 calories per pint"
Querying a member with an identifier rather than with a string

Figure 1-9. Querying a member with an identifier rather than with a string

To update the value of a member or to add a new member, you would use the = operator, same as before. Let's add a bostonCreamPie member to iceCream. Then query its value, verifying our work with Figure 1-10:

var iceCream = {
  chocolateFudgeBrownie: 4 * 260,
  halfBaked: 4 * 270,
  newYorkSuperFudgeChunk: 4 * 300,
  coffeeHeathBarCrunch: 4 * 280,
  cherryGarcia: 4 * 240,
  mudPie: 4 * 270,
  milkCookies: 4 * 270,
  cinnamonBuns: 4 * 290,
  chocolateChipCookieDough: 4 * 270,
  missionToMarzipan: 4 * 260
};
iceCream.bostonCreamPie = 4 * 250;
iceCream.bostonCreamPie + " calories per pint";
// "1000 calories per pint"
Writing a new value to a member named with an identifier

Figure 1-10. Writing a new value to a member named with an identifier

Creating an Array Literal

The members in iceCream are coded like a top-ten list. However, there's no way to have JavaScript query them that way. We couldn't ask, "What's my third favorite flavor?" for example. Plus, we have to name members and give them a value.

So, if we wanted to simply create a top-ten list of flavors, omitting the depressing calorie details, an object wouldn't do. For that we'd need an array, which is a subtype of the object value type. That is to say, an array is still an object; it just has some additional features.

One of those features is ordering values numerically with non-negative integers beginning at 0. JavaScript does so behind the scenes. So, you just list values in an array from first to last; JavaScript takes care of the numbering. Note that numbered values are referred to as elements rather than members.

Next click Clear in both Firebug panels. Then create an empty array literal named iceCream by typing a pair of square braces, followed of course by a semicolon.

var iceCream = [
];

Now add an element to iceCream like so:

var iceCream = [
  "Chocolate Fudge Brownie"
];

Just as object members are separated by commas, so too are array elements. We would add my second favorite flavor like so:

var iceCream = [
  "Chocolate Fudge Brownie",
  "Half Baked"
];

Then continue separating elements with commas to fill in the rest of my top ten. Note that final element, "Mission to Marzipan", is not followed by a comma. Note too that JavaScript numbers flavors from 0 to 9. Although "New York Super Fudge Chunk" is 3 in my heart, it's 2 to JavaScript:

var iceCream = [
  "Chocolate Fudge Brownie",
  "Half Baked",
  "New York Super Fudge Chunk",
  "Coffee Heath Bar Crunch",
  "Cherry Garcia",
  "Mud Pie",
  "Milk & Cookies",
  "Cinnamon Buns",
  "Chocolate Chip Cookie Dough",
  "Mission to Marzipan"
];

To query an element in iceCream, put its number in the [] operator. Note that an element's number is referred to as its index. Therefore, in Firebug, query a few elements in iceCream like so. Remember to stop and click Run prior to each comment.

var iceCream = [
  "Chocolate Fudge Brownie",
  "Half Baked",
  "New York Super Fudge Chunk",
  "Coffee Heath Bar Crunch",
  "Cherry Garcia",
  "Mud Pie",
  "Milk & Cookies",
  "Cinnamon Buns",
  "Chocolate Chip Cookie Dough",
  "Mission to Marzipan"
];
iceCream[0];
// "Chocolate Fudge Brownie"
iceCream[3];
// "Coffee Heath Bar Crunch"
iceCream[6];
// "Milk & Cookies"

Verify your work with Figure 1-11.

Creating an array and querying elements

Figure 1-11. Creating an array and querying elements

Now what if I try a new flavor and want to add it to the top 10. Say swap "Mission to Marzipan" for "Boston Cream Pie". How would you do that?

Yup, with the = operator. So, = writes a new value to an element or member. Try doing so in Firebug. Then query the new number 10, before verifying your work with Figure 1-12:

var iceCream = [
  "Chocolate Fudge Brownie",
  "Half Baked",
  "New York Super Fudge Chunk",
  "Coffee Heath Bar Crunch",
  "Cherry Garcia",
  "Mud Pie",
  "Milk & Cookies",
  "Cinnamon Buns",
  "Chocolate Chip Cookie Dough",
  "Mission to Marzipan"
];
iceCream[9] = "Boston Cream Pie";
iceCream[9];
// "Boston Cream Pie"
Writing a new value to an element in an array

Figure 1-12. Writing a new value to an element in an array

Admit it, you're skeptical that an array is of the object value type. Members are named with strings or identifiers, while elements are named with numbers. Or are they?

No. JavaScript names elements with strings, too. They're numeric ones but strings nonetheless. So, our array is like the following object:

var iceCream = {
  "0": "Chocolate Fudge Brownie",
  "1": "Half Baked",
  "2": "New York Super Fudge Chunk",
  "3": "Coffee Heath Bar Crunch",
  "4": "Cherry Garcia",
  "5": "Mud Pie",
  "6": "Milk & Cookies",
  "7": "Cinnamon Buns",
  "8": "Chocolate Chip Cookie Dough",
  "9": "Boston Cream Pie"
};

OK, so if array elements are not named with numbers, how come we read and write their values by number, not by string?

Sorry, JavaScript tricked you again. The [] operator converts the number you put in there to a string. If you give it a 3 to work with, it will return the value of the element named 3. To illustrate the point, query an element in iceCream with a string in Firebug:

var iceCream = [
  "Chocolate Fudge Brownie",
  "Half Baked",
  "New York Super Fudge Chunk",
  "Coffee Heath Bar Crunch",
  "Cherry Garcia",
  "Mud Pie",
  "Milk & Cookies",
  "Cinnamon Buns",
  "Chocolate Chip Cookie Dough",
"Mission to Marzipan"
];
iceCream["7"];
// "Cinnamon Buns"

Verify your work with Figure 1-13.

Querying an element with a string rather than with a number

Figure 1-13. Querying an element with a string rather than with a number

Similarly, we could query a member in an equivalent object literal with a number. Try it in Firebug, verifying your work with Figure 1-14:

var iceCream = {
  "0": "Chocolate Fudge Brownie",
  "1": "Half Baked",
  "2": "New York Super Fudge Chunk",
  "3": "Coffee Heath Bar Crunch",
  "4": "Cherry Garcia",
  "5": "Mud Pie",
  "6": "Milk & Cookies",
  "7": "Cinnamon Buns",
  "8": "Chocolate Chip Cookie Dough",
  "9": "Mission to Marzipan"
};
iceCream[5];
// "Mud Pie"
Objects may have elements, too.

Figure 1-14. Objects may have elements, too.

In Chapter 5, we'll explore some array-only features for manipulating elements. Those make elements in array magical compared to those in an object. It's sort of like how putting on the spidey suit turns ordinary Peter Parker into Spiderman.

Creating a Function Literal

Alright, it's trivial to query our ice cream array for what flavor I'd rank eighth:

var iceCream = [
  "Chocolate Fudge Brownie",
  "Half Baked",
  "New York Super Fudge Chunk",
  "Coffee Heath Bar Crunch",
  "Cherry Garcia",
  "Mud Pie",
  "Milk & Cookies",
  "Cinnamon Buns",
  "Chocolate Chip Cookie Dough",
  "Mission to Marzipan"
];
iceCream[7];
// "Cinnamon Buns"

But it's quite another to query whether a flavor like "Cinnamon Buns" is among my top ten, as the following sample and Figure 1-15 illustrate:

var iceCream = [
  "Chocolate Fudge Brownie",
  "Half Baked",
  "New York Super Fudge Chunk",
  "Coffee Heath Bar Crunch",
  "Cherry Garcia",
"Mud Pie",
  "Milk & Cookies",
  "Cinnamon Buns",
  "Chocolate Chip Cookie Dough",
  "Mission to Marzipan"
];
"Cinnamon Buns" === iceCream[0];
// false
"Cinnamon Buns" === iceCream[1];
// false
"Cinnamon Buns" === iceCream[2];
// false
"Cinnamon Buns" === iceCream[3];
// false
"Cinnamon Buns" === iceCream[4];
// false
"Cinnamon Buns" === iceCream[5];
// false
"Cinnamon Buns" === iceCream[6];
// false
"Cinnamon Buns" === iceCream[7];
// true
Determining whether a flavor is among the top ten, a real bear

Figure 1-15. Determining whether a flavor is among the top ten, a real bear

We wouldn't want to do that for a bunch of flavors. For eliminating this kind of drudgery, JavaScript provides a second object subtype named function. In addition to being able to contain members or elements, functions can also contain statements. Remember, those are commands you give to JavaScript.

Functions provide a way to save snippets of frequently run code to a place in memory, that is to say, for code reuse.

One of those would come in handy for determining whether a flavor is among my top ten. In Firebug, let's save a function literal to a variable named rankFlavor. To do so, type the keyword function, a pair of parentheses, and a pair of curly braces. Note that the parentheses contain a comma-separated list of identifiers, referred to as parameters or arguments. Those contain the values you pass to a function when you invoke it. Let's define a flavor parameter. Then if we pass our function "Cherry Garcia", JavaScript will assign that to flavor.

var iceCream = [
  "Chocolate Fudge Brownie",
  "Half Baked",
  "New York Super Fudge Chunk",
  "Coffee Heath Bar Crunch",
  "Cherry Garcia",
  "Mud Pie",
  "Milk & Cookies",
  "Cinnamon Buns",
  "Chocolate Chip Cookie Dough",
  "Mission to Marzipan"
];
var rankFlavor = function(flavor) {
};

In an object literal, the curly braces contain members, but in a function literal, the curly braces contain statements. Just type in the following for, if, and return statements for now. We'll explore if and for in Chapter 4 and return in Chapter 6. In a nutshell, this snippet of code compares the value of flavor to each element in iceCream. If flavor is among my top ten, JavaScript returns the value of the expression:

flavor + " is number " + (i + 1) + ".";

Note that i is the element's index in iceCream. Otherwise, JavaScript returns this expression:

flavor + " is not among my top 10.";

Let's pass rankFlavor()"Coffee Heath Bar Crunch" and then "Dublin Mudslide" like so, verifying our work with Figure 1-16:

var iceCream = [
  "Chocolate Fudge Brownie",
  "Half Baked",
  "New York Super Fudge Chunk",
  "Coffee Heath Bar Crunch",
  "Everything but the...",
  "Mud Pie",
  "Karamel Sutra",
  "Cinnamon Buns",
  "Milk & Cookies",
  "Mission to Marzipan"
];
var rankFlavor = function(flavor) {
  for (var i = iceCream.length; i --; ) {
    if (iceCream[i] === flavor) {
        return flavor + " is number " + (i + 1) + ".";
    }
  }
  return flavor + " is not among my top 10.";
};
rankFlavor("Coffee Heath Bar Crunch");
// "Coffee Heath Bar Crunch is number 4."
rankFlavor("Dublin Mudslide");
// "Dublin Mudslide is not among my top 10."
Saving a snippet of code to a function rather than typing it over and over

Figure 1-16. Saving a snippet of code to a function rather than typing it over and over

Though a function may seem very different from an object or array, it is quite similar. The following sample illustrates the point. Here, we add the elements from the iceCream array to the rankFlavor function. Therefore, rankFlavor() now contains ten elements in addition to a snippet of code. If we then modify the code snippet so that it iterates over the elements in rankFlavor() rather than those in iceCream, it works just as well, as Figure 1-17 displays:

var rankFlavor = function(flavor) {
  for (var i = rankFlavor.len; i --; ) {
    if (rankFlavor[i] === flavor) {
        return flavor + " is number " + (i + 1) + ".";
    }
  }
  return flavor + " is not among my top 10.";
};
rankFlavor[0] = "Chocolate Fudge Brownie";
rankFlavor[1] = "Half Baked";
rankFlavor[2] = "New York Super Fudge Chunk";
rankFlavor[3] = "Coffee Heath Bar Crunch";
rankFlavor[4] = "Everything but the...";
rankFlavor[5] = "Mud Pie";
rankFlavor[6] = "Karamel Sutra";
rankFlavor[7] = "Cinnamon Buns";
rankFlavor[8] = "Milk & Cookies";
rankFlavor[9] = "Mission to Marzipan";
rankFlavor.len = 10;
rankFlavor("New York Super Fudge Chunk");
// "New York Super Fudge Chunk is number 3."
rankFlavor("Peanut Brittle");
// "Peanut Brittle is not among my top 10."
The function rankFlavor() now contains ten elements in addition to a snippet of code.

Figure 1-17. The function rankFlavor() now contains ten elements in addition to a snippet of code.

Summary

In this chapter, we explored four value types to represent data with. For text like "Chocolate Fudge Brownie", JavaScript has a string value type. Numbers provide a way to do math, while booleans say yes and no.

The object value type provides a way to save related values to the same place in memory, sort of like a folder on your computer. Those may be named with an identifier or string. The array subtype offers a way to numerically order related values, while the function subtype contains snippets of frequently run code.

Although objects, arrays, or functions appear very different, they all may contain members named with a string or identifier or elements named with a non-negative integer. So, they're cut from the same cloth.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.171.125