Home > Articles

  • Print
  • + Share This
This chapter is from the book

Predefined Global Functions

JavaScript provides many predefined functions. Some of these functions, termed global functions, can be called from any part of a script—just as you can call the functions you have written. However, many predefined functions need to be treated as belonging to objects. This means that they can't be called in the same way that functions have been called so far (as you will learn later in the book). For the moment, let's look at global functions.

NOTE

JavaScript's predefined functions use native code (binary computer code) so you can call them but the code they contain cannot actually be seen. They are not written in JavaScript in the way that we write functions.

We have already come across and used some predefined functions such as the alert(), confirm(), and prompt() functions which bring up small dialog boxes to enable basic user interaction. These functions have been around for so long that the majority of browsers support them, although they are not actually part of core JavaScript. This means that in an environment other than a Web browser they may or may not be available. For the moment let's concentrate on the core JavaScript functions.

The predefined core JavaScript functions are listed below.

  • decodeURI()

  • decodeURIComponent()

  • encodeURI()

  • encodeURIComponent()

  • escape()

  • unescape()

  • eval()

  • isFinite()

  • isNaN()

  • Number()

  • parseFloat()

  • parseInt()

  • toString()

  • watch()

  • unwatch()

With the exception of watch() and unwatch(), you have already learned enough to be able to make use of all these functions. The watch() and unwatch() functions work with things called "object properties" to help in debugging. (As object properties are quite an advanced topic, and we haven't yet covered objects; those functions will be discussed later in the book.)

All these built-in functions either check or modify data in some way or another. Let's take a look at them now, one by one, and see what they do and how they can make our lives easier.

URI Encoding and Decoding

URIs (Uniform Resource Identifiers) is the most general name for the addresses used to access files on the Web. A "resource" is a unit of information that can be addressed. Not only can URIs be used to specify the address of a Web page, but they also can be used to send it information. You have probably seen Web sites where the address bar contains a question mark and lots of % symbols that are each followed by two numbers or letters. These are query strings used by sites, such as search engines, to send data from you to the server. The reason that much of the data is converted to what is called hex form, also called "escaped form"—when a character is converted to a % and the two characters of its hexadecimal value—is that some characters such as the space character can't be carried as they are in a URI.

When a form is used to submit data as a query string using the HTTP GET method, the browser automatically converts the characters that aren't allowed within a URI to their encoded hex values. To do this using JavaScript, you need to use built-in functions.

The original JavaScript functions for encoding and decoding URIs were the escape() and unescape() functions respectively. Let's look at an example to clarify just what they do:

var priceRange = "$4 - $6";
var escapedRange = escape(priceRange);
alert(escapedRange);

Figure 3.5 shows the output from the code.

Figure 3.5 Contents of the escapedRange variable after the escape() function has been applied to the priceRange variable.

The escape() function has replaced the $ and space characters with their escaped values, which are %24 and %20 respectively. The unescape() function acts in exactly the opposite way. When applied to the variable escapedRange the unescape() function will turn it back into text again.

Unfortunately the escape() and unescape() functions encode characters that do not need to be encoded. They are also slightly inconsistent from browser to browser in which characters they will encode. To remedy this, ECMAScript Edition 3 defined four new functions which are intended to replace the escape() and unescape() functions. These are the encodeURI(), decodeURI(), encodeURIComponent(), and decodeURIComponent() functions.

CAUTION

encodeURI(), decodeURI(), encodeURIComponent(), and decodeURIComponent() are only supported by Netscape 6+ and Internet Explorer 5.5+.

The encodeURI() function will encode all characters except for alphanumerical characters and the following characters which it leaves intact:

! # $ & ' ( ) * + , - . / : ; = ? @ _ ~

The encodeURIComponent() function is slightly different. It will encode all the characters that the encodeURI() function encodes but will also encode these characters:

# $ & + , / : ; = ? @

Therefore, it only leaves alphanumeric and the following characters intact.

! ' ( ) * - . _ ~

The reason for having two different encoding functions is that sometimes you may want to encode a whole URI including the http:// etc., and at other times you may want to only encode some data to be attached as a query string. Clearly, if you were to encode a complete URI with the encodeURIComponent() function, you would end up encoding the :// part of http:// too. Therefore, two different functions were created: One for thoroughly encoding URI components to be added as a query string; and another function for encoding the address before the query string.

The counterparts of these functions are the decodeURI() and decodeURIComponent() functions. The decodeURIComponent() function is similar to the unescape() function. It will decode all encoded characters. The decodeURI() function on the other hand will leave the following characters encoded:

# $ & + , / : ; = ? @

Evaluating Strings as Code

The eval() function is unusual in that it takes a string and processes it as code. Clearly, if this is not to cause an error, the string must be recognizable as JavaScript. To demonstrate this, try the code in Listing 3.3.

Listing 3.3 eval() Demo (evalDemo.htm)

<html>
<head>
<title>eval() Demo</title>

<script language="javascript" type="text/javascript">
<!--

var myCode = "alert('I was a string!')";

//-->
</script>

</head>
<body>

<h1>eval() Demo</h1>

</body>
</html>

In the single line of JavaScript code, a string is stored in the variable myCode. Although you can see it is a piece of JavaScript, JavaScript itself doesn't realize this. As far as it is concerned, it is just a series of characters strung together that it has been asked to store in a variable. Now try adding the following line after the variable declaration:

eval(myCode);

The eval() function will force the string to be evaluated as JavaScript and the alert box should appear.

For the moment we haven't covered enough to make practical use of the eval() function, but take note of it as it comes in very useful as you will see in later chapters.

Arithmetic Functions

Often programming is about manipulating numbers. It is no surprise then that JavaScript has a number of built-in functions designed to complement the arithmetic operators you learned about in Chapter 2.

JavaScript provides functions that check whether a piece of data is a number or what type of number it is, as well as functions which enable the manipulation of the numbers.

Numerical Checks on Data

There are two conditions that commonly cause arithmetic scripts to fail in JavaScript. One is that a number is, or becomes, infinite (or too large for JavaScript to handle, in which case the JavaScript interpreter treats the number as having the value Infinity). The other is that one of the pieces of data in an arithmetic operation is not a number. To check for these conditions where they are likely to occur, JavaScript provides two functions: isFinite() and isNaN().

Before examining these functions, it should be mentioned that there are three special values which have the data type number. These are Infinity, –Infinity, and NaN. Infinity and –Infinity represent, respectively, positive and negative numbers that have become too large for the JavaScript interpreter to handle or are genuinely infinite. They aren't of much practical use in an operation except to indicate that a number is too large for the JavaScript interpreter to reliably process. The other special value NaN, which stands for "Not a Number," indicates that an arithmetic operation could not be carried out:

alert("a" - 10); //alerts NaN

As you already may have guessed, the isFinite() function checks to make sure that a number is not one of the special values Infinity or –Infinity. If the number is finite and calculations can be carried out, then the function returns true, otherwise false.

It is rare that numbers to be entered directly into JavaScript are too big for it to process. It usually occurs when numbers are raised to excessive powers or divided by zero or a number very close to zero. Special care must be taken when accepting user input that might be used in these ways.

The isNaN() function is a little more tricky. It checks that a value is not a number. This allows us to check for numbers without checking for all of the other four data types in turn. Unfortunately, the function can cause some confusion at first because it returns false if a value is a number and true otherwise (after all it is checking that a value is not a number). See for example, the following:

alert(isNaN("a")); // alerts true
alert(isNaN(2));  // alerts false

If you really want it to return true for numbers, the logical NOT operator can be placed in front of the function thereby reversing the result.

Rather surprisingly NaN does not even evaluate as being equivalent to itself. Therefore:

CAUTION

NaN == NaN  // evaluates to false NaN === NaN // evaluates to false

To check for the value NaN, you must use the function isNaN():

isNaN(NaN)  // evaluates to true

The isNaN() function is especially useful when you collect numerical data from a visitor who is viewing your Web page. If the user enters non-numerical data either accidentally or intentionally then, without some appropriate error checking, your script will fail. It is always a good idea to use the isNaN() function to check any data you collect when you process it in any scripts. Let's look at Listing 3.4, where the getModulus() function we wrote earlier is improved:

Listing 3.4 Safely Finding the Modulus (getModulus.htm)

<html>
<head>
<title>Finding the Modulus</title>

<script language="javascript" type="text/javascript">
<!--

function getModulus()
{
   var theNum = prompt("Please enter a number", "");
   var theModulus = (theNum>=0)? theNum: -theNum;
   var msg = (isNaN(theModulus))? "Numbers only please.": 
        "The modulus of " + theNum + " is " + theModulus;
   alert(msg);
}

//-->
</script>

</head>
<body>

<h1>Finding the Modulus</h1>

<a href="javascript:getModulus()">Get Modulus</a>

</body>
</html>

When the link is clicked the function getModulus() is called. It prompts the user for a number and stores the input in the variable called theNum. The conditional operator is used on the following line to try to find the modulus (or absolute value) of the input. If this input is not numeric, then the result will be the value NaN. On the next line, the conditional operator is used again. This time the condition is the result from the function isNaN().

If the result of finding the modulus was NaN, then the isNaN() function will return true and the conditional operator will evaluate to its second operand which is the string "Numbers only please.". Note that the end of this line is a colon and not a semicolon. A new line for the third operand was started because it is quite long. If the result of the function was false, then the conditional operator will evaluate to its third operand, which is an expression. This expression combines the values of theNum and theModulus. It generates a string that tells the user, in a user-friendly way, the modulus of the number that was entered. Whichever operand the conditional operator evaluates to is assigned to the variable called msg. This message is then alerted to the user using the code on the final line of the function body.

The isNaN() function enabled you to output a result that has some intelligence to the user. In combination with the powerful control statements that you will learn about later in the chapter, the isNaN() function can be a very useful tool. Try to get used to using the function to check the data you collect with HTML forms or prompt boxes when this data should be numerical. It will help you make more professional scripts and allow you to avoid a significant number of potential errors.

Conversion Between String and Number

There are good reasons for converting strings to numbers and vice versa. For example, numbers collected from user input are always in the form of a string. Most times if you perform an arithmetic operation with this data it will automatically be converted to the number data type, but sometimes it is necessary to do it manually. Most notably is when you wish to add two numbers that are stored as strings. If you try to do this without converting their data types, then the two strings will simply be concatenated.

Conversely, in other settings, if you do want to concatenate two numbers which are of the data type number, you will need to convert their data type to string first. If you don't, they will simply be added.

The Number() and parseFloat() functions both take a single argument (or parameter if you prefer) and treat it in a very similar way. If the argument is a number they will return it unaltered, but if it is a string they will convert its data type to number (if possible) so that it can be used in arithmetic operations. They also both leave the number's floating point intact (unless all the digits are zeros in which case they are removed). They differ in two respects: how they treat other data types, and how they treat strings starting with numerical characters followed by non-numeric characters.

The parseFloat() function will always evaluate to NaN if used on a data type other than number or on a string, except when it contains only arithmetic characters. The Number() function, on the other hand, is a bit more flexible about the data with which it will work. As you might expect, it will convert false and null to 0, true to 1, and only undefined will be converted to NaN. Most of the time your choice of either of these two functions won't make a difference, but sometimes you may need one effect rather than the other—depending on how you want the function to treat non-numeric or string data. As you progress through the book and learn more, you will become better equipped to make that decision.

If a string starts with numbers and they are followed by other characters, the Number() function will realize it is not a number and return the value NaN. The parseFloat() function, on the other hand, exhibits a special behavior. It removes the non-numeric characters from the end of the numbers and returns the numeric characters as a number. For example, the following code shows how the Number() and parseFloat() functions handle strings passed to them as arguments:

Number("1.12 is a number");     // returns NaN
parseFloat("1.12 is a number"); // returns 1.12

Sometimes you may want to round off a number to get rid of its fractional part. The parseInt() function allows you to do exactly that. It converts a value's data type to number and rounds it down to an integer in a single step. Here is an example:

parseInt("2.1");     // returns 2
parseInt("2.5");     // returns 2
parseInt("2.99999"); // returns 2

This is useful, but the parseInt() function also has another less well known ability. It can convert numbers with a base between 2 and 36 to a decimal number (base 10). It does this by taking the number as its first argument, and then it allows you to specify the number's base as a second argument. The values can be either the string or number data type. For example, see the following:

parseInt("1111", 2); // returns 15

In this case, the number is the value "1111", and the base was specified as 2, which is binary. Therefore the first argument is converted from binary to its decimal equivalent, which is 15. Here are another few examples:

parseInt(20, 16);  // returns 32
parseInt("10", 8); // returns 8
parseInt("30", 4); // returns 12

Note that parseInt() still rounds down numbers before conversion:

parseInt("1111.1111", 2); // still returns 15
parseInt("ff.ffff", 16);  // returns 255

The value you give to parseInt() must be a string if it is above base 10. This is because numbers above base 10 may include alphabetical characters.

If numerical data is collected from a user and the numbers after the decimal point are not required, it is a good idea to use the parseInt() function and specify the number's base as 10. This will prevent it being interpreted as an octal number if the user began the number with a 0. The parseInt() function behaves in the same way as the parseFloat() function if a string starts with a number but continues with other characters; it will return only the number.

The final function for string-number conversion is the toString() function. It behaves exactly opposite of the Number(), parseFloat(), and parseInt() functions. Instead of converting strings containing numeric characters to numbers, it converts numbers to strings. If you want to add one set of digits to another without them being summed, it can be done with this function.

The syntax for the toString() function is different from that used for the Number(), parseFloat(), and parseInt() functions. Instead of taking a value as an argument typed into its parentheses, it uses something called the dot notation. In this case, the value must be stored in a data container such as a variable. The variable is then joined to the function call with a dot. Here is an example:

var myVar = 2;
myVar.toString(); // returns the string "2"

The dot tells the JavaScript interpreter to apply the toString() function to the contents of the variable myVar, which causes its data type to be changed to the data type string. You will learn more about dot notation as it applies to objects and their functions (methods) later. Let's have a look at the effect this has on a few examples:

var num1 = 12;
var num2 = 34;
alert(num1 + num2);
alert(num1 + num2.toString());
alert(num1.toString() + num2);

As you would expect, the expression on the third line sums the contents of the two variables num1 and num2. The toString() function causes the next two expressions to behave very differently though. Both functions would display the following alert box (see Figure 3.6).

Figure 3.6 After the toString() function is applied the numbers concatenate!

The toString() function has caused the operands of the + operator to concatenate rather than sum. Remember that in Chapter 2 you learned that if one of the operands of the + sign is a string, then it concatenates the two operands regardless of the data type of the other. Therefore there is no need to apply the toString() function to both operands. Applying it to one of them is enough.

It is probably the last thing you would expect, but the toString() function is also able to convert numbers between bases. It does exactly the opposite of the action taken by the parseInt() function. The difference is that rather than converting a number from a base between 2 and 36 to a decimal value, the toString() function takes decimal numbers and converts them to a base between 2 and 36. Of course JavaScript only outputs numbers as decimal values so the "numbers" the toString() function returns aren't of the data type number, but rather of the data type string. However, as they look like numbers to all intents and purposes, this doesn't usually matter.

To use toString() in this way, you simply give it the base you want to convert to as an argument:

var y = 10;
y.toString(8);  // returns 12 (10 decimal expressed to base 8)
var x = 0.5;
x.toString(16); // returns 0.8 (0.5 decimal expressed to base 16)

Note that as JavaScript accepts numbers in octal, decimal, or hexadecimal format, the toString() function converts from octal and hexadecimal numbers to the base you chose as well as from decimal.

By combining the parseInt() and toString() functions, it is possible to convert a number from any base between 2 and 36, to any other base between 2 and 36. As shown below, this can be written into a function so it can be used multiple times on the same page. Just remember that because the parseInt() function removes floating points the function won't be accurate with non-integers:

function convertNum(theNum, fromBase, toBase)
{
   var numBase10 = parseInt(theNum, fromBase);
   alert(numBase10.toString(toBase));
}

convertNum(1100, 2, 16);

In this example, the first line takes the 1100 from the argument theNum, and the argument fromBase specifies it as binary. The parseInt() function then converts it to decimal before it is stored in the variable numBase10. On the second line, the decimal value is converted using the argument toBase to specify the base as hexadecimal. This then alerts the value c, which is the hexadecimal equivalent of the binary value 1100. Note that the alert could just as easily be replaced with a return keyword for more practical use.

  • + Share This
  • 🔖 Save To Your Account