Working with Variables and Data Types in JavaScript

  • 6/15/2013

Defining and using variables

Variables should be familiar to programmers in just about any language. Variables store data that might change during the program’s execution lifetime. You’ve seen several examples of declaring variables throughout the previous chapters of this book. This section formalizes the use of variables in JavaScript.

Declaring variables

Variables are declared in JavaScript with the var keyword. The following are all valid variable declarations:

var x;
var myVar;
var counter1;

Variable names can contain uppercase and lowercase letters as well as numbers, but they cannot start with a number. Variables cannot contain spaces or other punctuation, with the exception of the underscore character (_). The following variable names are invalid:

var 1stCounter;
var new variable;
var new.variable;
var var;

Take a look at the preceding example. Whereas the first three variable names are invalid because characters are used that aren’t valid at all (or aren’t valid in that position, as is the case with the first example), the last variable name, var, is invalid because it uses a keyword. For more information about keywords or reserved words in JavaScript, refer to Chapter 3.

You can declare multiple variables on the same line of code, as follows:

var x, y, zeta;

These can be initialized on the same line, too:

var x = 1, y = "hello", zeta = 14;

Variable types

Variables in JavaScript are not strongly typed. It’s not necessary to declare whether a given variable will hold an integer, a floating point number, or a string. You can also change the type of data being held within a variable through simple reassignment. Consider this example, where the variable x first holds an integer but then, through another assignment, it changes to hold a string:

var x = 4;
x = "Now it's a string.";

Variable scope

A variable’s scope refers to the locations from which its value can be accessed. Variables are globally scoped when they are used outside a function. A globally scoped variable can be accessed throughout your JavaScript program. In the context of a webpage—or a document, as you might think of it—you can access and use a global variable throughout.

Variables defined within a function are scoped solely within that function. This effectively means that the values of those variables cannot be accessed outside the function. Function parameters are scoped locally to the function as well.

Here are some practical examples of scoping, which you can also find in the companion code in the scope1.html file:

<script type="text/javascript">
var aNewVariable = "I'm Global.";
function doSomething(incomingBits) {
    alert(aNewVariable);
    alert(incomingBits);
}
doSomething("An argument");
</script>

The code defines two variables: a global variable called aNewVariable and a variable called incomingBits, which is local to the doSomething() function. Both variables are passed to respective alert() functions within the doSomething() function. When the doSomething() function is called, the contents of both variables are sent successfully and displayed on the screen, as depicted in Figure 4-2 and Figure 4-3.

Figure 4-2

Figure 4-2 The variable aNewVariable is globally scoped.

Figure 4-3

Figure 4-3 The variable incomingBits is locally scoped to the function.

Here’s a more complex example for you to try.

Examining variable scope

  1. Using Visual Studio, Eclipse, or another editor, edit the file scoping.html in the Chapter04 sample files folder, which you can find in the companion content.

  2. Within the page, replace the TODO comment with the boldface code shown here (the new code can be found in the scoping.txt file in the companion content):

    <!doctype html>
    <html>
    <head>
        <title>Scoping Example</title>
        <script type="text/javascript">
        var aNewVariable = "is global.";
        function doSomething(incomingBits) {
            alert("Global variable within the function: " + aNewVariable);
            alert("Local variable within the function: " + incomingBits);
        }
        </script>
    
    </head>
    <body>
    <script type="text/javascript">
    
        doSomething("is a local variable");
        alert("Global var outside the function: " + aNewVariable);
        alert("Local var outside the function: " + incomingBits);
    
    </script>
    </body>
    </html>
  3. Save the file.

  4. View the file in a web browser. The result is three alerts on the screen.

    The first alert is this:

    httpatomoreillycomsourcemspimages1805568.jpg

    The second alert is this:

    httpatomoreillycomsourcemspimages1805570.jpg

    Click to view larger image

    The third alert looks like this:

    httpatomoreillycomsourcemspimages1805572.jpg

But wait a minute—examine the code. How many calls to the alert() function do you see? Hint: two are in the <HEAD> portion, and another two are within the <BODY> portion, for a total of four calls to the alert() function. So why are there only three alerts on the screen when four calls are made to the alert() function in the script?

Because this is a section on variable scoping (and I already explained the answer), you might already have figured it out. But this example demonstrates well how to troubleshoot JavaScript problems when the result isn’t what you expect.

The next procedure requires the use of the Firebug add-on to the Mozilla Firefox web browser. If you don’t yet have Firefox, download it from http://www.mozilla.com/firefox/.

Installing Firebug

This first procedure walks you through installing Firebug in Firefox. Firebug is very powerful and flexible.

  1. With Firefox installed, it’s time to get the Firebug add-on. Accomplish this task by going to http://www.getfirebug.com/. On that site, click the Install Firebug link. When you do so, you’ll be asked to choose the version of Firebug to install. Install the version that corresponds to your version of Firefox (or is as close as possible to the version of Firefox that you have).

  2. When you click the install link, you’ll be sent to Mozilla’s site, where you get to click another button, this one labeled “Add To Firefox.” A Software Installation dialog box opens, as shown in the following screen. Click Install Now.

  3. The installation completes when you restart Firefox, so click Restart Firefox after the add-on finishes downloading.

  4. Firefox closes and opens again, showing the installed add-on. Congratulations! Firebug is installed. Notice a small icon in the upper-right corner of the Firefox browser window. (The Firefox development team keeps moving buttons around, so the Firebug button might not be in the upper right when you read this.) Click the icon to open the Firebug console, shown here:

  5. Firebug’s JavaScript console is disabled, but don’t worry—the next procedure walks you through enabling and using it. Feel free to experiment with Firebug by enabling it.

With Firebug installed, you can troubleshoot the earlier problem you encountered in the scoping example of only three of the four expected alerts being displayed.

Troubleshooting with Firebug

  1. Open Firefox and open the scoping.html example that was created earlier in this chapter. The JavaScript code again executes as before, showing the three alerts. Close all three alerts. You end up with a blank page loaded in Firefox.

  2. Click the Firebug icon in Firefox browser window so that Firebug opens.

  3. Click the Script tab to open the Script pane, and notice that it is disabled. Click the arrow/triangle next to the word Script, and click Enabled.

  4. Click the Console tab, click the arrow/triangle next to the word Console, and click Enabled. You can see here that the Console is now activated:

  5. With both the Console and Script panes enabled, click the Reload button on the main Firefox toolbar. The page reloads, and the JavaScript executes again. All three alerts are displayed again, but notice now that Firebug has discovered an error, denoted by the red X indication in the Firebug Console:

  6. The error, as you can see, is that the variable incomingBits isn’t defined. This window also shows the line number at which the problem occurred. However, notice that because of the way the document is parsed, the line number in your original source code might not always be accurate. Regardless, you can see that incomingBits is not defined within the <BODY> section of the webpage because its scope is limited to the doSomething() function.

This procedure demonstrated not only the use of Firebug but also the effect of local versus global scoping of variables. Firebug is an integral part of JavaScript (and webpage) debugging. I invite you to spend some time with Firebug on just about any site to see how JavaScript, CSS, and HTML all interact.

In this procedure, the fix would be to define the variable incomingBits so that it gets instantiated outside the function call. (This new line of code follows and is in the file scoping-fixed.html in the Chapter04 folder in the companion content.) Because this variable was defined only as part of the function definition, the variable didn’t exist outside the function’s scope.

<!doctype html>
<html>
<head>
    <title>Scoping Example</title>
    <script type="text/javascript">
    var aNewVariable = "is global.";
    function doSomething(incomingBits) {
        alert("Global variable within the function: " + aNewVariable);
        alert("Local variable within the function: " + incomingBits);
    }

    </script>

</head>
<body>
<script type="text/javascript">
    var incomingBits = " must be defined if necessary.";
    doSomething("is a local variable");
    alert("Global var outside the function: " + aNewVariable);
    alert("Local var outside the function: " + incomingBits);

</script>
</body>
</html>

You can find more information about functions in Chapter 7.

The Date object

The Date object includes many methods that are helpful when working with dates in JavaScript—too many, in fact, to examine in any depth in a broad-based book such as this—but I do show you some examples that you might incorporate in your projects.

One of the unfortunate aspects of the Date object in JavaScript is that the implementation of its methods varies greatly depending on the browser and the operating system. For example, consider this code to return a date for the current time, adjusted for the local time zone and formatted automatically by the toLocaleDateString() method:

var myDate = new Date();
alert(myDate.toLocaleDateString());

When run in Internet Explorer 10 on a computer running Windows 8, the code results in a date like that shown in Figure 4-4.

Figure 4-4

Figure 4-4 The toLocaleString() method of the Date object in Internet Explorer 8.

Figure 4-5 shows what happens when that same code is executed in Firefox 12 on a Mac.

Figure 4-5

Figure 4-5 The toLocaleString() method of the Date object displays the message differently in Firefox on Mac.

The difference between these two dialog boxes might seem trivial, but if you were expecting to use the day of the week in your code (Monday, in the examples), you’d be in for a surprise. And don’t be fooled into thinking that the implementation issues are merely cross-operating system problems. Differences in the implementation of the Date object and its methods exist in browsers on products running Microsoft Windows as well.

The only way to resolve these and other implementation differences in your JavaScript application is to perform both cross-browser and cross-platform tests. Doing so adds time to the application development cycle, but finding and fixing a problem during development is probably less costly than finding and fixing the problem after users discover it in a production environment.

The Date object can be handed a number of arguments, ranging from zero arguments to up to seven arguments. When the Date object constructor is passed a single string argument, the string is assumed to contain the date. When it is passed a number type of argument, the argument is assumed to be the date in milliseconds since January 1, 1970, and when it is passed seven arguments, they’re assumed to be the following:

new Date(year, month, day, hours, minutes, seconds, milliseconds)

Remember the following points when using a Date object:

  • The year should be given with four digits unless you want to specify a year between the year 1900 and the year 2000, in which case you’d just send in the two-digit year, 0 through 99, which is then added to 1900. So, 2008 equals the year 2008, but 98 is turned into 1998.

  • The month is represented by an integer 0 through 11, with 0 being January and 11 being December.

  • The day is an integer from 1 to 31.

  • Hours are represented by 0 through 23, where 23 represents 11 P.M.

  • Minutes and seconds are both integers ranging from 0 to 59.

  • Milliseconds are an integer from 0 to 999.

Although the following procedure uses some items that won’t be covered until later chapters, you’re looking at the Date object now, so it’s a good time learn how to write the date and time to a webpage—a popular operation.

Writing the date and time to a webpage

  1. Using Visual Studio, Eclipse, or another editor, edit the file writingthedate.html in the Chapter04 sample files folder in the companion content.

  2. Within the page, add the code in boldface type shown here:

    <!doctype html>
    <html>
    <head>
        <title>the date</title>
    </head>
    <body>
        <p id="dateField">&nbsp;</p>
        <script type = "text/javascript">
        var myDate = new Date();
        var dateString = myDate.toLocaleDateString() + " " + myDate.toLocaleTimeString();
        var dateLoc = document.getElementById("dateField");
        dateLoc.innerHTML = "Hello - Page Rendered on " + dateString;
        </script>
    </body>
    </html>
  3. When saved and viewed in a web browser, you should receive a page like this (although the date you see will be different from what’s shown here):

The relevant JavaScript from the preceding steps is repeated here:

var myDate = new Date();
var dateString = myDate.toLocaleDateString() + " " + myDate.toLocaleTimeString();
var dateLoc = document.getElementById("dateField");
dateLoc.innerHTML = "Hello - Page Rendered on " + dateString;

The JavaScript related to the Date object is rather simple. It takes advantage of the toLocaleDateString() method, which you’ve already seen, and its cousin, toLocaleTimeString(), which returns the local time. These two methods are concatenated together with a single space and placed into the dateString variable, like this:

var dateString = myDate.toLocaleDateString() + " " + myDate.toLocaleTimeString();

The remainder of the code writes the contents of the dateString variable to the webpage, which is covered in more detail in Part II.

Counting down to a certain date in the future

  1. Using Visual Studio, Eclipse, or another editor, edit the file countdown.html in the Chapter04 sample files folder, which you can find in the companion content.

  2. Add the following code shown in boldface type to the page:

    <!doctype html>
    <html>
    <head>
        <title>the date</title>
    </head>
    <body>
        <p id="dateField">&nbsp;</p>
        <script type = "text/javascript">
        var today = new Date();
        var then = new Date();
        // January 1, 2014
        then.setFullYear(2014,0,1);
        var diff = then.getTime() - today.getTime();
        diff = Math.floor(diff / (1000 * 60 * 60 * 24));
        var dateLoc = document.getElementById("dateField");
        dateLoc.innerHTML = "There are " + diff + " days until 1/1/2014";
        </script>
    
    </body>
    </html>
  3. Save the page, and view it in a web browser. Depending on the date on your computer, the number of days represented will be different, but the general appearance of the page should look like this:

The exercise you just completed used some additional functions of both the Math and Date objects, namely floor() and getTime(). While this book covers a lot of ground, it’s not a complete JavaScript language reference. For that and even more information, refer to the ECMA-262 standard at http://www.ecma-international.org/publications/standards/Ecma-262.htm.

The next procedure shows how to calculate (or better yet, roughly estimate) the time it takes for a webpage to load in a person’s browser.

Calculating render time

  1. Using Visual Studio, Eclipse, or another editor, edit the file render.html in the Chapter04 sample files folder, which you can find in the companion content.

  2. Add the following code shown in boldface type to the page:

    <!doctype html>
    <html>
    <head>
        <title>the date</title>
        <script type = "text/javascript">
        var started = new Date();
        var now = started.getTime();
        </script>
    </head>
    <body>
        <p id="dateField">&nbsp;</p>
        <script type = "text/javascript">
        var bottom = new Date();
        var diff = (bottom.getTime() - now)/1000;
        var finaltime = diff.toPrecision(5);
        var dateLoc = document.getElementById("dateField");
        dateLoc.innerHTML = "Page rendered in " + finaltime + " seconds.";
        </script>
    
    </body>
    </html>
  3. Save the page, and view it in a web browser. Depending on the speed of your computer, web server, and network connection, you might receive a page that indicates only 0 seconds for the page load time, like this:

  4. If your page takes 0.0000 seconds, as mine did, you can introduce a delay into the page so that you can test it. (I’d never recommend doing this on a live site because I can’t think of a reason you’d want to slow down the rendering of your page! But introducing a delay can come in handy for testing purposes.) Using a for loop is a cheap and easy way to slow down the JavaScript execution:

    for (var i = 0; i < 1000000; i++) {
       //delay
    
    }

    The value I chose, 1000000, is arbitrary. You might need to choose a larger or smaller number to cause the desired delay. The final code looks like this:

    <!doctype html>
    <html>
    <head>
        <title>the date</title>
        <script type = "text/javascript">
        var started = new Date();
        var now = started.getTime();
        for (var i = 0; i < 1000000; i++) {
           //delay
        }
        </script>
    </head>
    <body>
        <p id="dateField">&nbsp;</p>
        <script type = "text/javascript">
        var bottom = new Date();
        var diff = (bottom.getTime() - now)/1000;
        var finaltime = diff.toPrecision(5);
        var dateLoc = document.getElementById("dateField");
        dateLoc.innerHTML = "Page rendered in " + finaltime + " seconds.";
        </script>
    
    </body>
    </html>
  5. Save the page, and view it again in a web browser. You should see some delay in the page load, which causes the value to be a positive number:

    When using this or similar functions to determine the page load times, to calculate the most accurate value, place the initial variable near the top of the page or script, and then place another one near the bottom of the page.

You just learned about a few of the more than 40 methods of the Date object. Many of these methods have UTC (Coordinated Universal Time) counterparts, meaning that they can get or set the date and time in UTC rather than local time. Table 4-4 lists the methods that return dates. With the exception of getTime() and getTimezoneOffset(), all these methods have UTC counterparts that are called using the format getUTCDate(), getUTCDay(), and so on.

Table 4-4 The get methods of the Date object

Method

Description

getDate()

Returns the day of the month

getDay()

Returns the day of the week

getFullYear()

Returns the four-digit year and is recommended in most circumstances over the getYear() method

getHours()

Returns the hours of a date

getMilliseconds()

Returns the milliseconds of a date

getMinutes()

Returns the minutes of a date

getMonth()

Returns the month of a date

getSeconds()

Returns the seconds of a date

getTime()

Returns the milliseconds since January 1, 1970

getTimezoneOffset()

Returns the number of minutes calculated as the difference between UTC and local time

Many of the get...() methods have siblings prefixed with set, as shown in Table 4-5. And like their get brethren, most of the set...() methods have UTC counterparts, except for setTime().

Table 4-5 The set methods of the Date object

Method

Description

setDate()

Sets the day of the month of a date

setFullYear()

Sets the four-digit year of a date; also accepts the month and day-of-month integers

setHours()

Sets the hour of a date

setMilliseconds()

Sets the milliseconds of a date

setMinutes()

Sets the minutes of a date

setMonth()

Sets the month as an integer of a date

setSeconds()

Sets the seconds of a date

setTime()

Sets the time using milliseconds since January 1, 1970

The Date object also has several methods for converting the date to a string in a different format. You already reviewed some of these methods, such as toLocaleDateString(). Other similar methods include toLocaleString(), toLocaleTimeString(), toString(), toISOString(), toDateString(), toUTCString(), and toTimeString(). Feel free to experiment with these, noting that toISOString() is a new method in the ECMA-262 version 5 specification and support for it might not be available in all browsers. (It’s notably missing from most versions of Internet Explorer.) The following simple one-line code examples will get you started experimenting. Try typing them in the address bar of your browser:

javascript:var myDate = new Date(); alert(myDate.toLocaleDateString());

javascript:var myDate = new Date(); alert(myDate.toLocaleString());

javascript:var myDate = new Date(); alert(myDate.toGMTString());

javascript:var myDate = new Date(); alert(myDate.toLocaleTimeString());

javascript:var myDate = new Date(); alert(myDate.toString());

javascript:var myDate = new Date(); alert(myDate.toISOString());

javascript:var myDate = new Date(); alert(myDate.toDateString());

javascript:var myDate = new Date(); alert(myDate.toUTCString());

javascript:var myDate = new Date(); alert(myDate.toTimeString());

You can also write these code samples without creating the myDate variable, like so:

javascript: alert(new Date().toUTCString());