Chapter 1. Introduction to JavaScript

JavaScript is an interpreted programming language with object-oriented (OO) capabilities. Syntactically, the core JavaScript language resembles C, C++, and Java, with programming constructs such as the if statement, the while loop, and the && operator. The similarity ends with this syntactic resemblance, however. JavaScript is a loosely typed language, which means that variables do not need to have a type specified. Objects in JavaScript map property names to arbitrary property values. In this way, they are more like hash tables or associative arrays (in Perl) than they are like structs (in C) or objects (in C++ or Java). The OO inheritance mechanism of JavaScript is prototype-based like that of the little-known language Self. This is quite different from inheritance in C++ and Java. Like Perl, JavaScript is an interpreted language, and it draws inspiration from Perl in a number of areas, such as its regular-expression and array-handling features.

The core JavaScript language supports numbers, strings, and Boolean values as primitive datatypes. It also includes built-in support for array, date, and regular-expression objects.

JavaScript is most commonly used in web browsers, and, in that context, the general-purpose core is extended with objects that allow scripts to interact with the user, control the web browser, and alter the document content that appears within the web browser window. This embedded version of JavaScript runs scripts embedded within HTML web pages. It is commonly called client-side JavaScript to emphasize that scripts are run by the client computer rather than the web server.

The core JavaScript language and its built-in datatypes are the subject of international standards, and compatibility across implementations is very good. Parts of client-side JavaScript are formally standardized, other parts are de facto standards, and other parts are browser-specific extensions. Cross-browser compatibility is often an important concern for client-side JavaScript programmers.

This chapter is a high-level overview of JavaScript; it provides the background information you need before embarking on a study of the language. As motivation and introduction, it includes some simple examples of client-side JavaScript code.

What Is JavaScript?

JavaScript is the subject of a fair bit of misinformation and confusion. Before proceeding any further, it is important to debunk two common and persistent myths about the language.

JavaScript Is Not Java

One of the most common misconceptions about JavaScript is that it is a simplified version of Java, the programming language from Sun Microsystems. Other than an incomplete syntactic resemblance and the fact that both Java and JavaScript can provide executable content in web browsers, the two languages are entirely unrelated. The similarity of names is purely a marketing ploy by Netscape and Sun (the language was originally called LiveScript; its name was changed to JavaScript at the last minute). However, JavaScript can, in fact, script Java (see Chapter 12 and 23).

JavaScript Is Not Simple

Because JavaScript is interpreted instead of compiled, it is often considered a scripting language instead of a true programming language. The implication is that scripting languages are simpler and that they are programming languages for nonprogrammers. The fact that JavaScript is loosely typed does make it somewhat more forgiving for unsophisticated programmers. And many web designers have been able to use JavaScript for limited, cookbook-style programming tasks.

Beneath its thin veneer of simplicity, however, JavaScript is a full-featured programming language, as complex as any and more complex than some. Programmers who attempt to use JavaScript for nontrivial tasks often find the process frustrating if they do not have a solid understanding of the language. This book documents JavaScript comprehensively so that you can develop a sophisticated understanding. If you are used to cookbook-style JavaScript tutorials, you may be surprised at the depth and detail of the chapters ahead.

Versions of JavaScript

Like any new technology, JavaScript evolved quickly when it was new. Previous editions of this book documented this evolution version by version, explaining exactly which language features were introduced in which version of the language. At the time of this writing, however, the language has stabilized and has been standardized by the European Computer Manufacturer’s Association, or ECMA.[*] Implementations of this standard include the JavaScript 1.5 interpreter from Netscape and the Mozilla Foundation, and the JScript 5.5 interpreter from Microsoft. Any web browser newer than Netscape 4.5 or Internet Explorer 4 supports the latest version of the language. As a practical matter, you are unlikely to encounter a noncompliant interpreter.

Note that the official name of the language, according to the ECMA-262 standard, is ECMAScript. But this awkward name is normally used only when making explicit reference to the standard. Technically, the name “JavaScript” refers only to language implementations from Netscape and the Mozilla Foundation. In practice, however, everyone calls the language JavaScript.

After a long period of stability for JavaScript, there are now some signs of change. The Firefox 1.5 web browser from the Mozilla Foundation includes a new JavaScript interpreter with the version number 1.6. This version includes new (nonstandard) array manipulation methods described in Array Extras, as well as support for E4X, which is described next.

In addition to the ECMA-262 specification that standardizes the core JavaScript language, ECMA has released another JavaScript-related standard. ECMA-357 standardizes an extension to JavaScript known as E4X, or ECMAScript for XML. This extension adds an XML datatype to the language along with operators and statements for manipulating XML values. At the time of this writing, E4X is implemented only by JavaScript 1.6 and Firefox 1.5. E4X is not documented formally in this book, but Chapter 21 includes an extended introduction in tutorial form.

Proposals for a fourth edition of the ECMA-262 specification, to standardize JavaScript 2.0, have been on the table for a number of years. These proposals describe a complete overhaul of the language, including strong typing and true class-based inheritance. To date, there has been little progress toward standardization of JavaScript 2.0. Nevertheless, implementations based on draft proposals include Microsoft’s JScript.NET language and the ActionScript 2.0 and ActionScript 3.0 languages used in the Adobe (formerly Macromedia) Flash player. At the time of this writing, there are signs that work on JavaScript 2.0 is resuming, and the release of JavaScript 1.6 can be seen as a preliminary step in this direction. Any new version of the language is expected to be backward-compatible with the version documented here, of course. And even once JavaScript 2.0 is standardized, it will take a few years before it is universally deployed in web browsers.

Client-Side JavaScript

When a JavaScript interpreter is embedded in a web browser, the result is client-side JavaScript. This is by far the most common variant of JavaScript; when most people refer to JavaScript, they usually mean client-side JavaScript. This book documents client-side JavaScript, along with the core JavaScript language that client-side JavaScript incorporates.

Client-side JavaScript combines the scripting ability of a JavaScript interpreter with the Document Object Model (DOM) defined by a web browser. Documents may contain JavaScript scripts, and those scripts can use the DOM to modify the document or control the web browser that displays the document. Put another way, we can say that client-side JavaScript adds behavior to otherwise static web content. Client-side JavaScript is at the heart of web development techniques such as DHTML (see Chapter 16) and architectures such as Ajax (see Chapter 20). The introduction to Chapter 13 includes an overview of the many capabilities of client-side JavaScript.

Just as the ECMA-262 specification defines a standard version of the core JavaScript language, the World Wide Web Consortium (W3C) has published a DOM specification that standardizes the features a browser must support in its DOM. (You’ll learn much more about this standard in Chapter 15, 16, and 17.) The core portions of the W3C DOM standard are well supported in all major web browsers. One notable exception is Microsoft Internet Explorer, which does not support the W3C standard for event handling.

Client-Side JavaScript Examples

When a web browser is augmented with a JavaScript interpreter, it allows executable content to be distributed over the Internet in the form of JavaScript scripts. Example 1-1 shows what this looks like: it is a simple JavaScript program, or script, embedded in an HTML file.

Example 1-1. A simple JavaScript program
<html>
<head><title>Factorials</title></head>
<body>
<h2>Table of Factorials</h2>
<script>
var fact = 1;
for(i = 1; i < 10; i++) {
    fact = fact*i;
    document.write(i + "! = " + fact + "<br>");
}
</script>
</body>
</html>

When loaded into a JavaScript-enabled browser, this script produces the output shown in Figure 1-1.

A web page generated with JavaScript
Figure 1-1. A web page generated with JavaScript

As you can see in this example, the <script> and </script> tags are used to embed JavaScript code in an HTML file. I’ll describe the <script> tag further in Chapter 13. The main feature of JavaScript demonstrated by this example is the use of the document.write() method.[*] This method is used to dynamically output HTML text into an HTML document while it is being loaded into the browser.

JavaScript can control not only the content of HTML documents but also the behavior of those documents. That is, a JavaScript program might respond in some way when you enter a value in an input field or hover the mouse over an image in a document. JavaScript does this by defining event handlers for the document—pieces of JavaScript code that are executed when a particular event occurs, such as when the user clicks on a button. Example 1-2 shows a simple HTML fragment that includes an event handler executed in response to a button click.

Example 1-2. An HTML button with a JavaScript event handler defined
<button onclick="alert('You clicked the button');">
Click here
</button>

Figure 1-2 illustrates the result of clicking the button.

The JavaScript response to an event
Figure 1-2. The JavaScript response to an event

The onclick attribute shown in Example 1-2 holds a string of JavaScript code that’s executed when the user clicks the button. In this case, the onclick event handler calls the alert() function. As you can see in Figure 1-2, alert() pops up a dialog box to display the specified message.

Example 1-1 and 1-2 highlight only the simplest features of client-side JavaScript. The real power of JavaScript on the client side is that scripts have access to the content of HTML documents. Example 1-3 contains a complete, nontrivial JavaScript program. The program computes the monthly payment on a home mortgage or other loan, given the amount of the loan, the interest rate, and the repayment period. It reads user input from HTML form fields, performs computations on that input, and then alters the document to display the results of the computation.

Figure 1-3 shows what the program looks like when displayed in a web browser. As you can see, it consists of an HTML form and some other text. But the figure captures only a static snapshot of the program. The addition of JavaScript code makes it dynamic: whenever the user changes the amount of the loan, the interest rate, or the number of payments, the JavaScript code recomputes the monthly payment, the total of all payments, and the total interest paid over the lifetime of the loan.

A JavaScript loan payment calculator
Figure 1-3. A JavaScript loan payment calculator

The first half of Example 1-3 is a simple CSS stylesheet and an HTML form, formatted within an HTML table. Note that the form elements define onchange or onclick event handlers. The web browser triggers these event handlers when the user changes the input or clicks on the Compute button displayed in the form, respectively. In each case, the value of the event handler attribute is a string of JavaScript code: calculate(). When the event handler is triggered, it executes this code, which calls the function calculate().

The calculate() function is defined in the second half of the example, inside a <script> tag. The function reads the user’s input from the form, does the math required to compute the loan payments, and inserts the results of these calculations into the document within <span> tags that are specially named with id attributes.

Example 1-3 is not a short example, but it is straightforward, and it is worth taking the time to look at it carefully. You shouldn’t expect to understand all the code at this point, but the HTML, CSS, and JavaScript are all commented, and studying this example will give you the feel for client-side JavaScript.[*]

Example 1-3. Computing loan payments with JavaScript
<html>
<head>
<title>JavaScript Loan Calculator</title>
<style>
/* This is a CSS style sheet: it adds style to the program output */
.result { font-weight: bold; }  /* For elements with class="result" */
#payment { text-decoration: underline; } /* For element with id="payment" */
</style>
</head>
<body>
<!--
  This is an HTML form that allows the user to enter data and allows
  JavaScript to display the results it computes back to the user. The
  form elements are embedded in a table to improve their appearance.
  The form itself is given the name "loandata", and the fields within
  the form are given names such as "interest" and "years". These
  field names are used in the JavaScript code that follows the form.
  Note that some of the form elements define "onchange" or "onclick"
  event handlers. These specify strings of JavaScript code to be
  executed when the user enters data or clicks on a button.
-->
<form name="loandata">
  <table>
    <tr><td><b>Enter Loan Information:</b></td></tr>
    <tr>
      <td>1) Amount of the loan (any currency):</td>
      <td><input type="text" name="principal" onchange="calculate();"></td>
    </tr>
    <tr>
      <td>2) Annual percentage rate of interest:</td>
      <td><input type="text" name="interest" onchange="calculate();"></td>
    </tr>
    <tr>
      <td>3) Repayment period in years:</td>
      <td><input type="text" name="years" onchange="calculate();"></td>
    </tr>
    <tr><td></td>
      <td><input type="button" value="Compute" onclick="calculate();"></td>
    </tr>
    <tr><td><b>Payment Information:</b></td></tr>
    <tr>
      <td>4) Your monthly payment:</td>
      <td>$<span class="result" id="payment"></span></td>
    </tr>
    <tr>
      <td>5) Your total payment:</td>
      <td>$<span class="result" id="total"></span></td>
    </tr>
    <tr>
      <td>6) Your total interest payments:</td>
      <td>$<span class="result" id="totalinterest"></span></td>
    </tr>
  </table>
</form>

<script language="JavaScript">
/*
 * This is the JavaScript function that makes the example work. Note that
 * this script defines the calculate() function called by the event
 * handlers in the form. The function reads values from the form
 * <input> fields using the names defined in the previous HTML code.  It outputs
 * its results into the named <span> elements.
 */
function calculate() {
    // Get the user's input from the form. Assume it is all valid.
    // Convert interest from a percentage to a decimal, and convert from
    // an annual rate to a monthly rate. Convert payment period in years
    // to the number of monthly payments.
    var principal = document.loandata.principal.value;
    var interest = document.loandata.interest.value / 100 / 12;
    var payments = document.loandata.years.value * 12;

    // Now compute the monthly payment figure, using esoteric math.
    var x = Math.pow(1 + interest, payments);
    var monthly = (principal*x*interest)/(x-1);

    // Get named <span> elements from the form.
    var payment = document.getElementById("payment");
    var total = document.getElementById("total");
    var totalinterest = document.getElementById("totalinterest");

    // Check that the result is a finite number. If so, display the
    // results by setting the HTML content of each <span> element.
    if (isFinite(monthly)) {
        payment.innerHTML = monthly.toFixed(2);
        total.innerHTML = (monthly * payments).toFixed(2);
        totalinterest.innerHTML = ((monthly*payments)-principal).toFixed(2);
    }
    // Otherwise, the user's input was probably invalid, so display nothing.
    else {
        payment.innerHTML = "";
        total.innerHTML = ""
        totalinterest.innerHTML = "";
    }
}
</script>
</body>
</html>

JavaScript in Other Contexts

JavaScript is a general-purpose programming language, and its use is not restricted to web browsers. JavaScript was designed to be embedded within, and provide scripting capabilities for, any application. From the earliest days, in fact, Netscape’s web servers included a JavaScript interpreter so that server-side scripts could be written in JavaScript. Similarly, Microsoft uses its JScript interpreter in its IIS web server and in its Windows Scripting Host product in addition to using it in Internet Explorer. Adobe uses a language derived from JavaScript for scripting its Flash player. And Sun bundles a JavaScript interpreter with its Java 6.0 distribution so that scripting capabilities can easily be added to any Java application (Chapter 12 shows how to do this).

Both Netscape and Microsoft have made their JavaScript interpreters available to companies and programmers who want to embed them in their applications. Netscape’s interpreter was released as open source and is now available through the Mozilla organization (see http://www.mozilla.org/js/). Mozilla actually provides two different versions of the JavaScript 1.5 interpreter. One is written in C and is called SpiderMonkey. The other is written in Java and, in a flattering reference to this book, is called Rhino.

If you are writing scripts for an application that includes an embedded JavaScript interpreter, you’ll find the first half of this book, documenting the core language, to be useful. The web-browser-specific chapters, however, will probably not be applicable to your scripts.

Exploring JavaScript

The way to really learn a new programming language is to write programs with it. As you read through this book, I encourage you to try out JavaScript features as you learn about them. A number of techniques make it easy to experiment with JavaScript.

The most obvious way to explore JavaScript is to write simple scripts. One of the nice things about client-side JavaScript is that anyone with a web browser and a simple text editor has a complete development environment; there is no need to buy or download special-purpose software in order to begin writing JavaScript scripts.

For example, you could modify Example 1-1 to display Fibonacci numbers instead of factorials:

<script>
document.write("<h2>Table of Fibonacci Numbers</h2>");
for (i=0, j=1, k=0, fib =0; i<50; i++, fib=j+k, j=k, k=fib){
    document.write("Fibonacci ("  + i +  ") = " + fib);
    document.write("<br>");
}
</script>

This code may be convoluted (and don’t worry if you don’t yet understand it), but the point is that when you want to experiment with short programs like this, you can simply type them up and try them out in your web browser using a local file: URL. Note that the code uses the document.write() method to display its HTML output so that you can see the results of its computations. This is an important technique for experimenting with JavaScript. As an alternative, you can also use the alert() method to display plain-text output in a dialog box:

alert("Fibonacci ("  + i +  ") = " + fib);

Note also that for simple JavaScript experiments like this, you can omit the <html>, <head>, and <body> tags in your HTML file.

For even simpler experiments with JavaScript, you can sometimes use the javascript: URL pseudoprotocol to evaluate a JavaScript expression and return the result. A JavaScript URL consists of the javascript: protocol specifier followed by arbitrary JavaScript code (with statements separated from one another by semicolons). When the browser loads such a URL, it executes the JavaScript code. The value of the last expression in the URL is converted to a string, and this string is displayed by the web browser as its new document. For example, you might type the following JavaScript URLs into the Location field of your web browser to test your understanding of some of JavaScript’s operators and statements:

javascript:5%2
javascript:x = 3; (x > 5)? "x is less": "x is greater"
javascript:d = new Date(); typeof d;
javascript:for(i=0,j=1,k=0,fib=1; i>5; i++,fib=j+k,k=j,j=fib) alert(fib);
javascript:s=""; for(i in navigator) s+=i+":"+navigator[i]+"\n"; alert(s);

In the Firefox web browser, you can also type single-line experiments into the JavaScript console, which you access through the Tools menu. Simply type in an expression you want to evaluate or a statement you want to execute. When using the console instead of the location bar, you omit the javascript: prefix.

While exploring JavaScript, you’ll probably write code that doesn’t work as you expect it to, and you’ll want to debug it. The basic debugging technique for JavaScript is like that in many other languages: insert statements into your code to print out the values of relevant variables so that you can try to figure out what is actually happening. As shown previously, you can use the document.write() or alert() methods to do this. (Example 15-9 provides a more sophisticated facility for logging debugging messages.)

The for/in loop (described in Chapter 6) is also useful for debugging. You can use it, along with the alert() method, to display a list of the names and values of all properties of an object, for example. This kind of function can be handy when exploring the language or trying to debug code.

If your JavaScript bugs are persistent and aggravating, you may be interested in an actual JavaScript debugger. In Internet Explorer, you can use Microsoft Script Debugger. In Firefox, you can use a debugger extension known as Venkman. Both tools are beyond the scope of this book, but you can find them easily with an Internet search. Another useful tool that is not strictly a debugger is jslint, which looks for common problems in JavaScript code (see http://jslint.com).



[*] The standard is ECMA-262, version 3 (available at http://www.ecma-international.org/publications/files/ecma-st/ECMA-262.pdf).

[*] “Method” is the OO term for function or procedure; you’ll see it used throughout this book.

[*] If your intuition tells you that it is a bad idea to intermingle HTML markup, CSS styles, and JavaScript code like this, you are not alone. The trend in JavaScript programming and web design circles is to keep content, presentation, and behavior in separate files. Unobtrusive JavaScript in Chapter 13 explains how to do this.

Get JavaScript: The Definitive Guide, 5th 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.