Chapter 4. The JavaScript Objects

The JavaScript objects are inherent components of the JavaScript language itself, and not the environment in which the JavaScript is processed. As such, they’ll always be available regardless of environment.

Among the basic JavaScript objects are those that parallel our data types, which we discussed in Chapter 2: String for strings, Boolean for booleans, and of course, Number for numbers. They encapsulate the primitive types, providing additional functionality beyond the basic conversion functionality we discussed in that chapter.

Three additional built-in objects provide necessary functionality as well: Math, Date, and RegExp. Math and Date are relatively self-explanatory; they provide basic math and date functionality. If you haven’t worked with regular expressions before, RegExp is the object that provides regular expression functionality. Regular expressions are powerful though extremely cryptic patterning capabilities that enable you to add very precise string matching to applications.

JavaScript also has one built-in aggregator object, the Array. All objects in JavaScript, in fact, are arrays, though we don’t typically treat the objects as arrays. I’ll discuss this in more detail later in the chapter. First, though, we’ll revisit the basic data type objects introduced earlier, as we explore exactly what it means to be an “object” in JavaScript.

Primitive Data Types As Objects

I’ll get into the details of JavaScript’s object-oriented nature later in the book. For now, we’ll look at the aspects of object-oriented functionality that are useful when working directly with the built-in JavaScript objects.

Objects in JavaScript have methods and other properties that you can access using the object property operator, represented by a period (.). For instance, to find the length of a string associated with a String object, you can access the object’s length property:

var myName = "Shelley";
alert(myName.length);

You also access object functions, called methods, via the same property operator, because methods are also considered object properties. Here is an example of the String object’s strike method, which encloses the string’s text within HTML opening and closing string element tags:

var myName = "Shelley";
alert(myName.strike()); // returns <strike>Shelley</strike>

This example might be somewhat confusing because it looks like I’m creating a string primitive rather than a String object. In the code, the variable myName is a string primitive variable, true. However, when a String method is invoked on the variable, it’s also an instance of a String object, with access to all of the String properties, including length and strike.

In Chapter 2, I mentioned how when an object method is invoked on a primitive data type, an object instance is created to wrap the primitive, the method call is processed, and then the object is discarded. The same principle applies to numbers and booleans as well.

However, instead of implicitly creating a String, Boolean, or Number object, you can explicitly create an object using the new keyword and the following syntax:

var myName = new String("Shelley");

The new keyword is important. If you omit it, you’ll get a string primitive rather than a string object. In other words, both of the following lines of JavaScript create string primitives:

var strName = "Shelley";
var strName2 = String("Shelley"); 

Returning to the String object, once you create a String object instance, you can access the primitive value it wraps (encloses) using another method that all the objects share, valueOf:

var myName = new String("Shelley");
alert(myName.valueOf());

You can also access the primitive value directly, as though it were a primitive data type:

var myName = new String("Shelley");
alert(myName);

To repeat what I said earlier in Chapter 2, which technique to use—string primitive or String object instance—depends on how you’re using the variable. If you’re going to be accessing the object properties, such as the String object’s length and strike methods, you’ll want to create the variable as an object. If you create a string primitive and then access it like an object, JavaScript will convert the primitive to an object when you access a String property, but it does so by converting the primitive to a temporary String object, and then discarding the object when it’s finished with the property. This isn’t efficient.

var strName ="Shelley"; // string as primitive
alert(strName.length); // String object is implicitly created, its data value set
to strName, and length method processed

However, if you’re using a string (or a number or boolean) as a primitive, you don’t need the object properties, and it’s more efficient just to use the string primitive technique of creating the variable:

var strName = "Shelley";
alert(strName); 

Because we’re exploring object properties in this chapter, the examples in the rest of this chapter create variables as object instances.

Boolean, Number, and String

Number and String object instances have their own unique properties, whereas Boolean does not. However, all three inherit certain properties and methods from a higher-level object, which I’ll cover in detail in Chapter 13. For now, among the methods that all the objects inherit are toString and valueOf. As the Boolean object has only inherited properties, I’ll use this object type to demonstrate each of these methods.

The Boolean Object

You actually can create an instance of a Boolean object in several different ways, depending on whether you want it to be set to an initial value of false or true. If you create the object using empty parentheses, the Boolean is created with a value of false:

var boolFlag = new Boolean();

You can also use a number to set the initial value, such as 0 for false:

var boolFlag = new Boolean(0);

Or 1 for true:

var boolFlag = new Boolean(1);

In addition, you can create and set the object using the literal true and false:

var boolFlag1 = new Boolean(false);
var boolFlag2 = new Boolean(true);

What’s interesting is that if you create the Boolean instance with an empty string, the object is set to an initial value of false. However, if you create the Boolean instance with any nonempty string, the object is set to an initial value of true:

var boolFlag1 = new Boolean(""); // set to false
var boolFlag2 = new Boolean("false"); // set to true

Ignore what the string says in the second line in the code; the string isn’t empty, so the object instance is set to an initial value of true. You can test this for yourself by using the valueOf method, as Example 4-1 demonstrates.

Example 4-1. Testing the value of a Boolean instance using the valueOf method

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Boolean valueOf</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[

function newBool() {
   var boolFlag = new Boolean("false");
   alert(boolFlag.valueOf());
}

//]]>
</script>
</head>
<body onload="newBool()">
<p>Some page content</p>
</body>
</html>

Figure 4-1 shows the alert window and the Boolean instance value of true when the page is accessed in Opera. The valueOf method returns the value of the primitive that the Boolean (and Number and String) encapsulates.

The result of calling valueOf on a Boolean instance

Figure 4-1. The result of calling valueOf on a Boolean instance

The method toString returns the same value as valueOf, except as a string, "true", rather than true:

var boolFlag = new Boolean("false");
var strFlag = boolFlag.toString(); // string containing "true"

The Number Object, Static Properties, and Instance Methods

Before getting into the Number object, a note about instance versus object properties.

The two methods we used with the Boolean object in the preceding section are known as instance methods because the methods are associated with the object instance, boolFlag, rather than the object class, Boolean. Neither the toString nor the valueOf method would be very useful without being attached to an instance, with its unique data to convert to a string or be returned as a value.

Another type of object method is known as a static method. Static methods don’t operate on the instance data, but instead are called directly on the object class. All of the Math object’s methods, which I’ll cover later in the chapter, are static methods:

var newNum = Math.abs(oldNum);

The same instance versus object implementation also applies to properties that aren’t methods. Specifically, five Number properties are accessible only via the Number object itself. These are:

Number.MAX_VALUE

The maximum number representation in JavaScript

Number.MIN_VALUE

The smallest positive number representation in JavaScript

Number.NaN

Represents Not-a-Number

Number.NEGATIVE_INFINITY

Represents negative infinity

Number.POSITIVE_INFINITY

Represents infinity

Typically, you use the infinity properties only to test when an overflow condition has occurred. An overflow occurs when a number is created that is either too small or too large, and therefore exceeds the MIN_VALUE or MAX_VALUE property:

var someValue = -1 * Number.MAX_VALUE  * 2;
alert(someValue);

someValue = Number.MAX_VALUE * 2;
alert(someValue);

The alert would display the value of -infinity for NEGATIVE_INFINITY first, followed by infinity for POSITIVE_INFINITY.

I use the Number object in the listing of the four properties to highlight the importance of accessing these properties on the Number object itself, not on a Number instance. If you try to access these properties on a Number instance, a value of undefined will be returned:

var someNumber = new Number(3.0);
var maxValue = someNumber.MAX_VALUE; // undefined

The Number object’s instance methods have to do with conversion—to a string, to a locale-specific string, to a given precision- or fixed-point representation, and to an exponential notation. The Number object has three instance methods:

toExponential

Returns a string representing the number using exponential notation

toFixed

Returns a string representing the number in fixed-point notation

toPrecision

Returns a string representing the number using a specific precision

The global methods valueOf and toString are also supported for Number instances, as is an additional method, toLocaleString. The latter returns a locale-specific version of the number. Unlike with Boolean, the toString method for the Number object instance also takes one parameter, a base, which you can use to convert the number between decimal and hexadecimal, or between decimal and octal, and so on.

Example 4-2 demonstrates the various Number object instance methods.

Example 4-2. The Number object instance methods

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Number methods</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[

function numbers() {

   // Number  methods
   var newNumber = new Number(34.8896);

   document.writeln(newNumber.toExponential(3) + "<br />");
   document.writeln(newNumber.toPrecision(3) + "<br />");
   document.writeln(newNumber.toFixed(6) + "<br />");

   var newValue = newNumber.valueOf();

   document.writeln(newValue.toString(2) + "<br />");
   document.writeln(newValue.toString(8) + "<br />");
   document.writeln(newValue.toString(10) + "<br />");
   document.writeln(newValue.toString(16) + "<br />");
}
//]]>
</script>
</head>
<body onload="numbers()">
<p>Some page content</p>
</body>
</html>

Figure 4-2 shows the results of running this JavaScript application in Safari.

The Number object instance methods in Safari

Figure 4-2. The Number object instance methods in Safari

The first method the code invokes is toExponential, which the number of digits appearing after the decimal point passed in as a parameter—in this case, 3. The second method is toPrecision, with a value of 3 also passed as a parameter, representing the number of significant digits to include in the string transformation. The third method the code called, toFixed, is the number of digits to print out after the decimal—rounded if applicable.

The code then obtains the value of the Number object using the valueOf method and assigns this value to a new variable before using the new variable with the toString method calls. It does this because toString uses the base parameter only if it’s used with an actual number, not an object. The variable newNumber holds an object, not a number. Only after we get the actual number and assign it to a second variable can we use toString with different base representations.

The String Object

The String object is probably the most used of the built-in JavaScript objects. You can explicitly create a new String object using the new String constructor, passing the literal string as a parameter:

var sObject = new String("Sample string");

The String object has several methods, some associated with working with HTML and several not. Table 4-1 lists the properties and methods available via String object instances.

Table 4-1. String object methods

Method

Description

Arguments

valueOf

Returns the string literal that the String object is wrapping

None

length

The property, not the method, with the length of the string literal

Use without parentheses

anchor

Creates an HTML anchor

String with anchor title

big, blink, bold, italics, small, strike, sub, sup

Format and return the String object’s literal value as HTML

None

charAt, charCodeAt

Return either a character (charAt) or character code (charCodeAt) at a given position

Integer representing position, starting at position zero (0)

indexOf

Returns the starting position of the first occurrence of a substring

Search substring

lastIndexOf

Returns the starting position of the last occurrence of a substring

Search substring

link

Returns HTML for the link

URL for the href attribute

concat

Concatenates strings together

Strings to concatenate onto the String’s literal string

split

Splits the string into tokens based on some separator

Separator and maximum number of splits

slice

Returns a slice from the string

Beginning and ending positions of the slice

substring, substr

Return a substring

Beginning and ending locations of the string

match, replace, search

Regular expression match, replace, and search

String with regular expression

toLowerCase, toUpperCase

Convert case

None

One of the non-HTML-specific methods, concat, takes two strings and returns a result with the second string concatenated onto the first. Example 4-3 demonstrates how to create a String object and use the concat method.

Example 4-3. Creating a String object and calling the concat method

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>String concatenation</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[

function stringConcat() {

   var sObj = new String();
   var sTxt = sObj.concat("This is", " a ", "new string");
   alert(sTxt);
}
//]]>
</script>
</head>
<body onload="stringConcat()">
<p>Some page content</p>
</body>
</html>

There is no specified limit to the number of strings you can concatenate with the String concat method. However, I rarely use the concat method; if I’m going to be building a string, I prefer using string primitives and the string concatenation operator (+) simply because it is less cumbersome.

Of course, you’re going to want to minimize concatenation as much as possible. Each time you concatenate one string to another, you’re creating a new string object. Strings are immutable in JavaScript, which means you can’t actually change a string once you’ve created it. When you assign a new string value or modify an old value, you’re really just creating a new string which exists in memory, along with the old one, until the application goes out of scope (typically when the function is finished):

var newStr = "this is";
newStr+= " a new string"; // old string is discarded, new string is created

If you did a lot of concatenation, the performance of the application could suffer. However, most uses of string concatenation are simple variations of putting together a string with a few variable values, and you can use it without worrying much about performance.

The HTML formatting methods—anchor, link, big, blink, bold, italics, sub, sup, small, and strike—generate strings that enclose the String object instance’s literal value within HTML element tags. Example 4-4 demonstrates how these formatting methods work, using one specific string with different methods.

Example 4-4. Working with the String object’s formatting functions

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>String HTML</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[

function stringHTML() {

var someString = new String("This is the test string");

document.writeln(someString.big() + "<br />");
document.writeln(someString.blink() + "<br />");
document.writeln(someString.sup() + "<br />");
document.writeln(someString.strike() + "<br />");
document.writeln(someString.bold() + "<br />");
document.writeln(someString.italics() + "<br />");
document.writeln(someString.small() + "<br />");
document.writeln(someString.link('http://www.oreilly.com'));
}                                     
//]]>                                    
</script>                              
</head>                                   
<body onload="stringHTML()">
<p>Some page content</p>
</body>
</html>

Figure 4-3 shows the derived page opened in Firefox. Note the HTML styling added to each variation of the string. What the image can’t show is the blinking action of the string formatted with blink. blink is deprecated HTML, which means that more modern HTML and XHTML specifications have stopped supporting it, and eventually, browsers will stop supporting it as well. It definitely won’t validate within a web page given a strict Document Type Declaration (DOCTYPE), such as in Example 4-4. However, if you use it with document.writeln, the page validates because the XHTML validators see the proper use of JavaScript, not the generated results. If you copy the generated results into a new document and run these with any XHTML validator, or try to serve the pages as XHTML rather than HTML, you’ll receive an error for the use of blink.

Page created using application

Figure 4-3. Page created using Example 4-4 application

Warning

Even if you don’t receive an error directly, you should avoid using the HTML format methods (other than anchor and link) as much as possible, primarily because they don’t use the more modern Cascading Style Sheets (CSS) styling. And whatever you do, avoid blink: it’s an obnoxious behavior.

Returning to the String object’s instance methods, the charAt and charCodeAt methods return the character and the Unicode character code, respectively, at a given location. The methods take one parameter—an index of the character to be returned:

var sObj = new String("This is a test string");
var sTxt = sObj.charAt(3);
document.writeln(sTxt);

The index values begin at zero; to return the character at the fourth position, pass in the value 3.

The substr and substring methods, as well as slice, return a substring given two parameters, though what’s returned and the parameters differ among the three methods. The substr method takes a starting index and the length of the substring as parameters, whereas substring extracts the characters between two given indexes:

var sTxt = "This is a test string";
var ssTxt = sTxt.substr(5,8); // returns "is a tes"
var ssTxt2 = sTxt.substring(5,8); // returns "is "

If the stop index is less than the start for substring, the method swaps the two values. If you omit the end parameter for both, the rest of the string after the start index is returned. If the second index or length is longer than the string, the length of the string is used.

The slice method is similar to substring in that it takes two indexes, but unlike substring, if the stop index is less than the start index, the values aren’t swapped, and an empty string is returned:

var ssTxt2 = sTxt.substring(4,1); // returns his
var ssTxt3 = sTxt.slice(4,1); // returns empty string

As the code examples in this section demonstrate, you can use the String methods with a string literal, as well as a String object. Just as a reminder: the application processing the JavaScript converts the variable to an object, calls the method, and then reconverts the object back to a primitive variable, discarding the object.

The indexOf and lastIndexOf methods return the index of a search string, with the former returning the first occurrence and the latter returning the last:

var sTxt = "This is a test string";
var iVal = sTxt.indexOf("t");
document.writeln(iVal);

Example 4-3 demonstrated concatenating strings together. If you want to do the reverse—split a string apart—use the split method. This method has two parameters: the first is the character that marks each break; the second, which is optional, is the number of splits to perform.

The JavaScript in Example 4-5 takes a string and splits it on the comma (,)—performing a break only on the first three commas. The resultant values are then split on the equals sign (=).

Example 4-5. Using the String split function to break a string into tokens

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Gotta Split</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[

function splitString() {

   var inputString = new
String('firstName=Shelley,lastName=Powers,state=Missouri,statement="This is a test,
of split"');
   var arrayTokens = inputString.split(',',3);

   // process split on commas
   for (var i = 0; i < arrayTokens.length; i++) {
      document.writeln(arrayTokens[i] + "<br />");

      // now split on equals and write just value
      var newTokens = arrayTokens[i].split('=');
      document.writeln(newTokens[1] + "<br /><br />");
   }
}
//]]>
</script>
</head>
<body onload="splitString()">
<p>Some page content</p>
</body>
</html>

The result of running this JavaScript application is the following output to the web page:

firstName=Shelley
Shelley

lastName=Powers
Powers

state=Missouri
Missouri

This is a very handy way of processing form fields before they’re submitted to the server, pulling in individual values from strings attached to the URL of the page, or a result returned from an Ajax call, which I demonstrate toward the end of the book.

Returning to the String object instance methods, toUpperCase and toLowerCase, convert the string to all upper- or lowercase characters, respectively, and return the converted result:

var someString = new String("Mix of upper and lower");
var newString = someString.toUpperCase(); // uppercases all of the letters

These are particularly useful functions if case is going to be an issue because you can convert the string to all upper- or lowercase before processing.

There is also one static method on the String object—fromCharCode:

var s = String.fromCharCode(345,99,99,76);
document.writeln(s);

The fromCharCode method takes Unicode values separated by commas and returns a string. However, as we discussed in Chapter 2, you can also embed Unicode characters directly into a string.

The last String methods depend on a concept known as regular expressions. Because regular expressions are associated with another built-in JavaScript object, RegExp, we’ll look at all of the regular-expression-related String methods in the next section.

Regular Expressions and RegExp

Regular expressions are arrangements of characters that form a pattern that you can then use against strings to find matches, make replacements, or locate specific substrings. Most programming languages support some form of regular expression, and JavaScript is no exception.

You can create a regular expression explicitly using the RegExp object, although you can also create one using a literal. The following uses the explicit option:

var searchPattern = new RegExp('s+');

The next line of code demonstrates the literal RegExp option:

var searchPattern = /s+/;

In both cases, the plus sign (+) in the search pattern following the character s matches one or more consecutive uses of s in a string. The forward slashes with the literal (/s+/) mark that the object being created is a regular expression and not some other type of object.

The RegExp Methods: test and exec

The RegExp object has only two unique instance methods of interest: test and exec. The test method determines whether a string passed in as a parameter matches with the regular expression. The following example tests the pattern /JavaScript rules/ against the string to see whether a match exists:

var re = /JavaScript rules/;
var str = "JavaScript rules";
if (re.test(str)) document.writeln("I guess it does rule") ;

Matches are case-sensitive: if the pattern is /Javascript rules/, the result is false. To instruct the pattern-matching functions to ignore case, follow the second forward slash of the regular expression with the letter i:

var re =/Javascript rules/i;

The i option is a flag that modifies the pattern matching, forcing the matching process to disregard case. The other flags are g for a global match and m to match over many lines.

The global match instructs the pattern-matching process to find all occurrences of a pattern, regardless of where the pattern is in the line. Without the use of the global flag g, only the first match would either be replaced or returned. The multiline flag m enables the use of line-specific characters, such as ^ for the start of a line and $ for the end, to work across multiple lines.

If you’re creating a RegExp object instance, the flags are passed as a second parameter:

var searchPattern = new RegExp('s+', 'g');

In the following snippet of code, the RegExp method exec searches for a specific pattern, /JS*/, across the entire string (g), ignoring case (i). A string with the matched pattern, available in the result array at the 0 index, is printed to the web page, as is the location where the next match will begin:

var re = new RegExp("JS*","ig");
var str = "cfdsJS *(&YJSjs 888JS";
var resultArray = re.exec(str);
while (resultArray) {
  document.writeln(resultArray[0]);
  document.writeln(" next match starts at " + re.lastIndex + "<br />");
        resultArray = re.exec(str);
}

The pattern described in the regular expression is the letter J, followed by any number of S’s. Since the i flag is used, case is ignored, so the js substring is found. As the g flag is given, the RegExp lastIndex property is set to the location where the last pattern was found on each successive call, so each call to exec finds the next pattern. In all, the four items found are printed, and when no others are found, a null value is assigned to the array. Because the loop condition is just the array variable, setting the array to null results in the loop terminating. Running this code results in the following output:

JS next match starts at 6
JS next match starts at 13
js next match starts at 15
JS next match starts at 21

The exec method returns an array, but the array entries are not all matches, as you might have initially guessed, but rather are the current match and any parenthesized substrings. If you use parentheses to match substrings within the overall string, they are included in successive array entries in the resultant array following the overall matched string, contained in the 0 index for the array. If you altered the preceding code snippet to appear as in Example 4-6, other array entries would show the substring pattern matches.

Example 4-6. String and substring matching with RegExp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>RegExp string matching</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[

window.onload=function() {
  var re = /(ds)+(j+s)/ig;
  var str = "cfdsJS *(&dsjjjsYJSjs 888dsdsJS";
  var resultArray = re.exec(str);
  while (resultArray) {
    document.writeln(resultArray[0]);
    document.writeln(" next match starts at " + re.lastIndex + "<br />");
    for (var i = 1; i < resultArray.length; i++) {
      document.writeln("substring of " + resultArray[i] + "<br />");
    }
    document.writeln("<br />");
    resultArray = re.exec(str);
  }
}
//]]>
</script>
</head>
<body>
<p></p>
</body>
</html>

The result from this example is:

dsJS next match starts at 6
substring of ds
substring of JS

dsjjjs next match starts at 16
substring of ds
substring of jjjs

dsdsJS next match starts at 31
substring of ds
substring of JS

These code samples demonstrated a couple of the special regular expression characters. There are several regular expression characters, one of which is the plus sign (+) in Example 4-6. Typically, books and articles throw all such characters into a table, and then provide a couple of examples that use several together in a long and complicated pattern, and that’s the extent of the coverage. Because of this, many people have a lot of trouble putting together regular expressions, and as a consequence, their applications don’t work as they originally anticipated. I think regular expressions are important enough to at least provide several examples, from simple to complex. If you have worked with regular expressions before, you might want to skip this section—unless you need the review.

Though you use RegExp methods in applications, you’ll primarily use regular expressions and the RegExp object with the String object’s regex methods: replace, match, and search. The rest of the examples in this section demonstrate regular expressions using these methods.

Working with Regular Expressions

You use the backslash character (\), usually called the escape character, to escape whatever character follows it. In JavaScript regular expressions, the use of an escape character results in two behaviors. If the character is usually treated literally, such as the letter s, it’s treated as a special character following the escape character—in this case, a whitespace (space, tab, form feed, or line feed). Conversely, when you use the backslash with a special character, such as the plus sign earlier, the character that follows the backslash is treated as a literal.

The JavaScript application in Example 4-7 searches a string for instances of a space that’s followed by an asterisk, and replaces the combination with a dash. Normally, the asterisk is used to match zero or more of the preceding characters in a regular expression, but in this case, we want to treat it as a literal.

Example 4-7. Escape character in regular expressions

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>RegExp</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[

function matchString() {

var regExp = /\s\*/g;
var str = "This *is *a *test *string";
var resultString = str.replace(regExp,'-');
alert(resultString);

}
//]]>
</script>
</head>
<body onload="matchString()">
<p>Some page content</p>
</body>
</html>

Applying the regular expression against the string results in the following line:

This-is-a-test-string

The regular expression pattern used in Example 4-7 is a very handy expression to keep in mind. If you want to replace all occurrences of spaces in a string with dashes, regardless of what’s following the spaces, use the pattern /\s+\g in the replace method, passing in the hyphen as the replacement character.

Four of the regular expression characters are used to match specific occurrences of characters: the asterisk (*) matches the character preceding it zero or more times, the plus sign (+) matches the character preceding it one or more times, the question mark (?) matches zero or one of the preceding characters, and the period (.) matches exactly one character.

Two patterns of interest are the greedy match (.*) and the lazy star (.*?). In the first, because a period can represent any character, the asterisk matches until the last occurrence of a pattern, rather than the first. If you’re looking for anything within quotes, you might think of using /".*"/. If you use regular expressions with a string, such as:

test='"one" or this is also a "test"'

the match begins with the first double quote and continues until the last one, not the second one:

"one" or this is also a "test"

The lazy star forces the match to end on the second occurrence of the double quote, rather than the last occurrence:

"one"

Example 4-8 contains a more complex regular expression. The application looks for a match on a date in the form of month name followed by space, day of month, and then year. The date begins after a colon.

Example 4-8. Patterns of repeating characters

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Find Date</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[

function findDate() {

   var regExp = /:\D*\s\d+\s\d+/;
   var str = "This is a date: March 12 2009";
   var resultString = str.match(regExp);
   alert("Date" + resultString);

}
//]]>
</script>
</head>
<body onload="findDate()">
<p>Some page content</p>
</body>
</html>

Looking more closely at the regular expression, the first character in the pattern is the colon, followed by the backslash with a capital letter D: \D. This sequence is one way to look for any nonnumeric character; the asterisk following it means that any number of nonnumeric characters will match. The next part in the regular expression is a whitespace character, \s, followed by another new pattern, \d. Unlike the earlier sequence, \D, the lowercase letter means to match numbers only. The plus sign following this sequence means match one or more numbers. Another space follows \s in the pattern and then another sequence of numbers, \d+.

When matched against the string using String match, the date preceded by the colon is found, returned, and printed:

Date: March 12 2009

In the example, \D matches any nonnumeric character. Another way to create this particular match is to use the square brackets with a number range, preceded by the caret character (^). If you want to match any character except for numbers, use the following:

[^0-9]

The same holds true for \d, except now you want numbers, so leave off the caret:

[0-9]

If you wish to match on more than one character type, you can list each range of characters within the brackets. The following matches on any upper- or lowercase letters:

[A-Za-z]

Using this alternative set of patterns, you also could give the regular expression in Example 4-8 as follows:

var regExp = /:[^0-9]*\s[0-9]+\s[0-9]+/;

You can use the caret (^) in another pattern: you use it and the dollar sign ($) to capture specific patterns relative to the beginning and end of a line. When you use a caret outside the brackets, you match any sequence beginning a line; the dollar sign matches any sequence ending a line. In the following code snippet, the match is not successful because the character that was searched did not occur at the beginning of the line:

var regExp = /^The/i;
var str = "This is the JavaScript example";

However, the following would be successful:

var regExp = /^The/i;
var str = "The example";

If the multiline flag is given (m), the caret matches on the first character after the line break:

var regExp = /^The/im;
var str = "This is\nthe end";

The same positional pattern matching holds true for the end-of-line character. The following doesn’t match:

var regExp = /end$/;
var str = "The end is near";

But this does:

var regExp = /end$/;
var str = "The end";

If the multiline flag is used, it matches at the end of the string and just before the line break:

var regExp = /The$/im;
var str = "This is really the\nend";

The use of parentheses is significant in regular expression pattern matching. Parentheses match and then remember the match. The remembered values are stored in the result array:

var rgExp = /(^\D*[0-9])/
var str = "This is fun 01 stuff";
var resultArray = str.match(rgExp);
document.writeln(resultArray);

In this code snippet, the array prints out This is fun 0 twice, separated by a comma, indicating two array entries. The first result is the match; the second, the stored value from the parentheses. If, instead of surrounding the entire pattern, you surround only a portion, such as /(^\D*)[0-9]/, this results in:

This is fun 0,This is fun

Only the surrounded matched string is stored.

Parentheses can also help you to switch material around in a string. RegExp recognizes special characters, labeled $1, $2, and so on, up to $9, that store substrings discovered through the use of the capturing parentheses. Example 4-9 finds pairs of strings separated by one or more dashes and switches the order of the strings.

Example 4-9. Swapping strings using regular expressions

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>swap</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[

function swapWords() {

   var rgExp = /(\w*)-*(\w*)/
   var str = "Java---Script";
   var resultStrng = str.replace(rgExp,"$2-$1");
   alert(resultStrng);
}
//]]>
</script>
</head>
<body onload="swapWords()">
<p>Some page content</p>
</body>
</html>

Here’s the result of that JavaScript:

Script-Java

Notice that the number of dashes is also stripped down to just one dash. This example introduces another very popular pattern-matching character sequence, \w. This sequence matches any alphanumeric character, including the underscore (underline). It’s equivalent to [A-Za-z0-9_]. Its converse is \W, which is equivalent to any nonalphanumeric character.

The last regular expression characters we’ll examine in detail are the vertical bar (|) and the curly braces. The vertical bar indicates optional matches. For instance, the following matches to either the letter a or the letter b:

a|b

You can use more than one character with vertical bars to provide more options:

a|b|c

The curly braces indicate repetition of the preceding character a set number of times. The following searches for two s characters together:

s{2}

Regular expressions are extremely useful when processing data from Ajax applications, and when validating form contents, as I will demonstrate in Chapter 8.

The Date Object

In JavaScript, you use the Date object to create instances of dates. Once you have a date object instance, you can use several methods to access or modify the date (or components of the date) such as the year, day, and month.

Creating a date without passing in any parameters produces a date based on the client machine’s date and time:

var dtNow = new Date();

Or, you can pass in optional parameters to the Date constructor to create a specific date. One option is to pass in the number of milliseconds since January 1, 1970 at 12:00:00:

var dtMilliseconds = new Date(5999000920);

The preceding code snippet results in the following date:

Wed, 11 Mar 1970 10:23:20 GMT

You can also use a string to create a date as long as you use the proper date format:

var newDate = new Date("March 12, 1980 12:20:25");

You can forgo the time in the string and just get a date with times set to zeros:

var newDate = new Date('March 12, 2008');

You can also pass in each value of the date as integers, in order of year, month (as 0 to 11), day, hour, minutes, seconds, and milliseconds:

var newDt = new Date(1977,11,23);
var newDt = new Date(1977,11,24,19,30,30,30);

The Date object instance methods feature several get and set methods for retrieving or setting specific components of the date. Each of the following gets specific values from the date according to local times:

getFullYear

The four-digit year

getHours

The hours component of the date/time

getMilliseconds

The milliseconds component of the date/time

getMinutes

The minutes component of the date/time

getMonth

The month, as a number between 0 and 11 inclusive

getSeconds

The seconds component of the date/time

getDay

Returns the number representing the day of the week, starting with 0 for Sunday and ending with 6 for Saturday

getDate

Returns the day of the month

Here are the Coordinated Universal Time (UTC) equivalents:

  • getUTCFullYear

  • getUTCHours

  • getUTCMilliseconds

  • getUTCMinutes

  • getUTCMonth

  • getUTCSeconds

  • getUTCDay

  • getUTCDate

Most of the get methods have equivalent set methods that set a component’s value within a Date. An example would be setYear to set the year, setSeconds to set the seconds, or setUTCMonth to set a UTC month. The only method that doesn’t have an equivalent set method is getDay. Also, two methods are deprecated, meaning they won’t be available in the future. These are getYear and setYear.

Another method, getTimezoneOffset, returns the number of minutes (+ or –) of the offset of the local computer from UTC. Because I’m writing this in St. Louis, which is in UTC-5, I would get a value of 300 when calling this method against a local time date.

Six methods convert the date to a formatted string:

toString

Outputs the string in local time

toGMTString

Formats the string using GMT standards

toLocaleDateString and toLocaleTimeString

Output the date and the time, respectively, using the locale

toLocaleString

Converts the string using the current locale

toUTCString

Formats the string using UTC standards

Also, three static methods are available directly on the Date object. Date.now returns the current date and time; Date.parse returns the number of milliseconds since January 1, 1970; and Date.UTC returns the number of milliseconds given the longest form of the constructor, described earlier:

var numMs = Date.UTC(1977,11,24,30,30,30);

Note

Date.now is not standard. Creating a date primitive without using the new constructor also returns the current time:

var rightNow = Date();

Example 4-10 demonstrates several of the Date methods, including those that set date components, and methods to display the derived date.

Example 4-10. Several string setting and formatting Date methods

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Date</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[

function testingDate() {

   // new date
   var dtNow = new Date();

   // set day, month, year
   dtNow.setDate(18);
   dtNow.setMonth(10);
   dtNow.setYear(1954);
   dtNow.setHours(7);
   dtNow.setMinutes(2);

   // output formatted
   document.writeln(dtNow.toString() + "<br />");
   document.writeln(dtNow.toLocaleString() + "<br />");
   document.writeln(dtNow.toLocaleDateString() + "<br />");
   document.writeln(dtNow.toLocaleTimeString() + "<br />");
   document.writeln(dtNow.toGMTString() + "<br />");
   document.writeln(dtNow.toUTCString());
}                                               
//]]>                                           
</script>                                
</head>                                  
<body onload="testingDate()">
<p>Some page content</p>
</body>
</html>

The result of running Example 4-10 in Firefox 3.1 is:

Thu Nov 18 1954 07:02:19 GMT-0600 (CST)
Thu Nov 18 07:02:19 1954
11/18/1954
07:02:19
Thu, 18 Nov 1954 13:02:19 GMT
Thu, 18 Nov 1954 13:02:19 GMT

Given so many date options, it might be puzzling to figure out which specific locale to use in an application. I’ve found that a good rule of thumb is to reference everything in the web page reader’s local time if her actions are isolated—such as when placing an order at an online store. However, if the person’s actions are in relation to the actions of others, especially within an international audience (such as a weblog for comments), I recommend setting times to UTC to maintain a consistent framework for all of your readers.

The Math Object

Arithmetic isn’t math, at least in JavaScript, where the operators for basic arithmetic described in Chapter 3 are not associated with the Math object. The Math object provides mathematical properties and methods, such as LN10, which is the logarithm of 10, and log(x), which returns the natural logarithm of x. It doesn’t participate in simple arithmetic, such as addition and subtraction.

Unlike the other JavaScript objects, all of the Math object’s properties and methods are static. This means you don’t create a new instance of Math to get access to the functionality; you access the methods and properties directly on the shared object itself:

var newValue = Math.SQRT1;

The Math Properties

Several constant properties are associated with the Math object, including the familiar pi, as well as the square root of 2 and the national logarithm of 10. This following is a list of all of these properties:

E

The value of e, the base of the natural logarithms

LN10

The natural logarithm of 10

LN2

The natural logarithm of 2

LOG2E

The approximate reciprocal of LN2—the base-2 logarithm of e

LOG10E

The approximate reciprocal of LN10—the base-10 logarithm of e

PI

The value of pi

SQRT1_2

The square root of 1/2

SQRT2

The square root of 2

Math in programming depends somewhat on the underlying architecture, and this includes how each browser that provides a JavaScript engine implements some of the math functions, as well as the operating system, machine, and so on. As such, the results of the trigonometric functions may vary somewhat, but hopefully not so much as to make the functions unusable within this context.

The Math Methods

The Math methods are relatively straightforward. Regardless of variable type, all arguments passed to the Math functions are converted to numbers first. You don’t have to do any conversion in your code.

The abs function takes an argument representing a numeric value and returns the absolute value of that number. If the number is negative, the positive value is returned. The variable pVal is set to 3.4 in the following code snippet:

var nVal = -3.45;
var pVal = Math.abs(nVal);

Several trigonometric methods are also available: sin, cos, tan, acos, asin, atan, and atan2. These provide, respectively, the sine, cosine, tangent, arc cosine, arc sine, arc tangent, and computation of the angle between an x-point and the origin. Each takes a specific type of numeric argument and returns a result that is meaningful to the method:

Math.sin(x)

A specific angle, in radians

Math.cos(x)

A specific angle, in radians

Math.tan(x)

An angle, in radians

Math.acos(x)

A number between –1 and 1

Math.asin(x)

A number between –1 and 1

Math.atan(x)

Any number

Math.atan2(py,px)

The y and x coordinates of a point

The Math.ceil method rounds a number to the next highest whole number. The following two lines of JavaScript set the variable pVal to 4:

var nVal = 3.45;
var pVal = Math.ceil(nVal);

The following lines of JavaScript set pVal to –3:

var nVal = -3.45;
var pVal = Math.ceil(nVal);

The Math.floor method, on the other hand, rounds a number down—returning the next lowest whole number. The following JavaScript sets pVal to 3:

var nVal = 3.45;
var pVal = Math.floor(nVal);

The following lines of JavaScript sets pVal to –4:

var nVal = -3.45;
var pVal = Math.floor(nVal); 

The Math.round method rounds to the nearest integer; whether this is higher or lower depends on the value. A value of 3.45 rounds to 3, whereas a value of 3.85 rounds to 4. A midway number, such as 3.5, would round up to 4. The result is the nearest integer regardless of whether the value is negative or positive.

Math.exp(x) calculates a number equivalent to e, the base of natural logarithms, raised to the value of the argument passed to the method:

var nVal = Math.exp(4) // equivalent to e4

Math.pow raises any number to a given power:

var nVal = Math.pow(3,2) // 32 or 9

Math.min and Math.max compare two or more numbers and return the minimum or the maximum:

var nVal = 1.45;
var nVal2 = 4.5;
var nVal3 = -3.33;
var nResult = Math.min(nVal, nVal2, nVal3) // set to -3.33
var nResult2 = Math.max(nVal, nVal2, nVal3) // set to 4.5

The last method, Math.random, generates a number between 0 (inclusive) and 1 (exclusive):

var nValue = Math.random();

You can multiply this value by 10 or 100 (or by any value) to generate random numbers beyond a value of 1. Unfortunately, you can’t set limits to generate a random number within a range of values. You can emulate this behavior, though, as Example 4-11 demonstrates.

Example 4-11. A random-number generator

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Random Quote</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
  //<![CDATA[

function getQuote() {

   var quoteArray = new Array(5);
   quoteArray[0] = "Quote one";
   quoteArray[1] = "Quote two";
   quoteArray[2] = "Quote three";
   quoteArray[3] = "Quote four";
   quoteArray[4] = "Quote five";

   iValue = Math.random(); // random number between 0 and 1
   iValue *= 5; // multiply by 5 to move the decimal
   iValue = Math.floor(iValue); // round to nearest integer
   alert(quoteArray[iValue]);
}

//]]>
</script>
</head>
<body onload="getQuote();">
  <p>some content</p>
</body>
</html>

An array is created with five quotes. A function is called when the page loads, which uses several Number and Math functions to generate an application number (between 0 and 4 inclusive). The number is used to access an array element, which is then output.

JavaScript Arrays

A JavaScript Array is an object, just like String or Math. As such, you create it with a constructor:

var newArray = new Array('one','two');

You also can create an array as a literal value, which doesn’t require the explicit use of the Array object:

var newArray = ['one','two'];

Unlike String and Number, the JavaScript application immediately converts the literal to an object of type Array, assigning the result to the variable. String, Number, and Boolean literals are converted to objects only when object methods are called, and then discard the object instances immediately afterward.

Once the Array instance is created, you can access array elements by their index value—the number representing their location in the array:

alert(newArray[0]);

Array indexes start at 0 and go up to the number of elements, minus 1. So, an array of five elements would have indexes from 0 to 4.

Arrays don’t have to be one-dimensional. It’s not uncommon to have an array in which each element has multiple dimensions, and the way to manage this in JavaScript is to create an array where each element is an array itself. In the following code snippet, an array of three-dimensional values is created:

var threedPoints = new Array();
threedPoints[0] = new Array(1.2,3.33,2.0);
threedPoints[1] = new Array(5.3,5.5,5.5);
threedPoints[2] = new Array(6.4,2.2,1.9);

If the inner array contains the x, y, and z coordinates in order, you can access the z coordinate of the third point with the following code:

var newZPoint = threedPoints[2][2]; // remember, arrays start with 0

To add array dimensions, continue creating arrays in elements:

threedPoints[2][2] = new Array(4.4,4.6,44) // and so on
var newthreedZPoint = threedPoints[2][2][1];

You do not have to know the number of elements for an array ahead of time. As the examples demonstrate, you can create an array with a fixed number of elements in the array declaration, or just add elements as you go along. You can also set the size of an array by adding its nth or last element first:

var testArray = new Array();
testArray[99] = 'some value'; // testArray is now an array with 100 elements

To find the length of an array (the number of elements), use the Array property called length:

alert(testArray.length); // outputs 100

If you access the length of a multiple-dimension array, you’ll get the number of elements for only a particular dimension:

alert(threedPoints[2][2].length); // outputs 3
alert(threedPoints[2].length); // outputs 3
alert(threedPoints.length); // outputs 3

In addition to length, the Array object also has a few other properties of interest, and several methods. One such method is splice, which allows you to insert and/or remove elements from an array—a rather handy method to have. In the following code snippet, splice adds two elements and removes two, starting at index 2 (the third element):

var fruitArray = new Array('apple','peach','orange','lemon','lime','cherry');
var removed = fruitArray.splice(2,2,'melon','banana');
document.writeln(removed + "<br />");
document.writeln(fruitArray);

The preceding code generates the following two lines:

orange,lemon
apple,peach,melon,banana,lime,cherry

The removed elements are returned as an array from the splice method call.

The slice method slices an array and returns the result:

var newFruit = fruitArray.slice(2,4); // returns an array of 3 elements: melon,
banana, and lime

The concat method concatenates one array onto the end of the other, returning an array with entries of apple, peach, melon, banana, lime, cherry, orange, and lemon:

var newFruit = fruitArray.concat(removed);

Neither concat nor slice alters the original array. Instead, they return a new array containing the results of the operation.

In the examples, I’ve been printing out the arrays directly. The JavaScript engine converts the arrays to a string, using a default separator of a comma (,) between array elements. If you want to designate a different separator, use the join method to generate a string, passing in what you want used as the separator, such as a space:

var strng = fruitArray.join(" ")

You can also reverse the order of the elements in an array using the reverse method:

fruitArray.reverse();

In many cases, the exact order of the elements in an array is unimportant. Sometimes, though, you want to have the order preserved, such as when the array serves as a queue. Several methods are useful for maintaining arrays as queues or lists, which we’ll look at next.

FIFO Queues

You can use arrays to track a queue of items, where each is added FIFO (first-in, first-out). Four handy Array methods can maintain queues, lists, and the like: push, pop, shift, and unshift.

The push method adds elements to the end of an array, whereas the unshift method adds elements to the beginning of the array. Both return the new length of the array.

The pop method removes the last element of the array, and the shift method removes the first element. Both return the element retrieved from the array.

All four methods modify the array—either adding or removing elements permanently from the array. Example 4-12 demonstrates how you can maintain a FIFO queue in JavaScript.

Example 4-12. FIFO queue using Array methods

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>FIFO</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
    //<![CDATA[

function pushPop() {

   // create FIFO queue and add items using push
   var fifoArray = new Array();
   fifoArray.push("Apple");
   fifoArray.push("Banana");

   var ln = fifoArray.push("Cherry");

   // print out length and array
   document.writeln("length is " + ln + " and array is " + fifoArray + "<br />");

   // use shift to shift the items off the array
   for (var i = 0; i < ln; i++) {
      document.writeln(fifoArray.shift() + "<br />");
   }

   // print out length
   document.writeln("length now is " + fifoArray.length + "<br /><br />");

   // now, same with unshift
   var fifoNewArray = new Array();

   fifoNewArray.unshift("Learning");
   fifoNewArray.unshift("Java");
   ln = fifoNewArray.unshift("Script");

   document.writeln("length is " + ln + " and array is " + fifoNewArray + "<br
/>");

   // unshift
   for (var i = 0; i < ln; i++) {
     document.writeln(fifoNewArray.pop() + "<br />");
   }
   document.writeln("new length is " + fifoNewArray.length );
}

//]]>
</script>
</head>
<body onload="pushPop();">
</body>
</html>

The first thing to notice in this example is that I’ve paired shift and push, and unshift and pop. The reason for this is the order in which these methods work. The push method adds an element to the end of an array, and as each new element is added, it pushes the first elements to the front of the array. The pop method removes the items from the end of the array first, creating a LIFO list (last-in, first-out)—a perfectly legitimate queue, but not what we’re after with the program. We want the first element added to be the first element retrieved. The shift method removes elements from the top of the array, which does suit our needs.

The same applies to unshift and pop. The unshift method adds items to the top of an array, each new item pushing the older ones farther down the list, while pop removes them from the bottom of the queue first. This again maintains the order of items, and this is what we’re after—not the order of the array elements themselves, but the order in which they’re added.

The result of running this JavaScript in our target browsers (all except for current versions of Internet Explorer, which don’t return a length when using unshift) is the following:

length is 3 and array is Apple,Banana,Cherry
Apple
Banana
Cherry
length now is 0

length is 3 and array is Script,Java,Learning
Learning
Java
Script
new length is 0

Example 4-12 also demonstrated how for loops can traverse an array. Rather than have to individually write out each shift or pop method call, the application iterated through the same call the same number of times as elements in the array. This example is small, but you can imagine how much of a time-saver this can be with a larger array.

Typically, when traversing an array with a for loop, the variable that’s adjusted with each loop is incremented (or decremented when counting down) and is used as an array index:

for (var i = 0; i < someArray.length; i++) {
    alert(someArray[i]);
}

However, you do not have to use the index; it’s there if you need it. And as implied, you count down with a for loop as well as count up:

for (var i = someArray.length-1; i >=  0; i--) ...

As an alternative, you can use the for...in loop to access each array element:

var programLanguages = new Array
('C++','Pascal','FORTRAN','BASIC','C#','Java','Perl','JavaScript');
for (var itemIndex in programLanguages) {
   document.writeln(programLanguages[itemIndex] + "<br />");
}

Other methods are associated with the array that require the use of a callback function, which we will cover in Chapter 5.

Test Your Knowledge: Quiz

  1. Comma-separated strings are a common data format. How would you create an array of elements when given a comma-separated string? Write the code for the following string, and then access the third element: "cats,dogs,birds,horses".

  2. The \b special character can define a word boundary, and \B matches on a nonword boundary. Define a regular expression that will find all occurrences of the word fun in the following string and replace them with power:

    "The fun of functions is that they are functional."
  3. Create code to get today’s date, modify it by a week, and print out the new date.

  4. Given a number of 34.44, write code that would round the number down. Do the same to round the number up.

  5. Given a string such as the following, use pattern matching and replace all existing punctuation with commas, and then load it as an array and print out each value:

    var str = "apple.orange-strawberry,lemon-.lime";

Test Your Knowledge: Answers

  1. Use the String.split method, passing in a comma as the delimiter. Solution is:

    var animalString = "cats,dogs,birds,horses";
    var animalArray = String.split(animalString,",");
    alert(animalArray[2]); // alert box displays birds
  2. The solution is:

    var funPattern = /\bfun\b/;
    var strToSearch = "The fun of functions is that they are functional";
    var afterMatch = strToSearch.replace(funPattern,"power");
  3. There is no Date function that manipulates weeks, but we know that a week is seven days at 24 hours a day, for a total of 168 hours. Use the getHours method to get the current date’s hours, add 168 to it, reset the hours, and then print out the date:

    var dtNow = new Date();
    var hours = dtNow.getHours();
    hours+=168;
    dtNow.setHours(hours);
    document.writeln(dtNow.toString());
  4. Math.floor can round the number down, and Math.ceil can round the number up. The solutions are:

    var baseNum = 34.44;
    var numFloor = Math.floor(baseNum); // returns 34
    var numCeil = Math.ceil(baseNum); // returns 35
  5. The solution is:

    var strToAlter = "apple.orange-strawberry,lemon-.lime";
    var puncPattern = /[\.|-]/g;
    var afterMatch = strToAlter.replace(puncPattern,",");
    var fruits = afterMatch.split(',');
    for (var i = 0; i < fruits.length; i++)
         document.writeln(fruits[i]);

Get Learning JavaScript, 2nd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.