Debugging JavaScript programs

A quick reference guide to finding errors without the aid of a debugging utility

Everyone makes mistakes writing JavaScript programs. Errors don't know experts from novices, so the next time you get an error message while trying to play a JavaScript program you've written, don't feel bad. JavaScript provides error messages as a means to help you spot mistakes. This column describes the errors you are likely to get when writing a JavaScript program and what to do about them.

They say that novels are not written, but rewritten. Certainly the same goes for computer programs, including those written in JavaScript. Bugs are the bane of any programmer, and debugging is part of the program development process.

Unfortunately, client-side JavaScript currently (circa 1996 -- ed.) lacks a debugging utility, so finding errors in your script becomes a lesson in deductive reasoning. You cannot -- as yet, anyway -- set a breakpoint and have your browser display the contents of registers or variables if a program terminates unexpectedly.

Tools for debugging JavaScript

This classic JavaWorld article, written in 1996, presents time-tested tips for understanding the nature of JavaScript bugs and working them out simply and strategically. See "Ajax: Tools of the trade" (Nate Schutta, 2009) and "JavaScript tools for the HTML5 generation" (Peter Wayner, 2012) to learn about tools that can help you write and debug modern JavaScript programs.

Debugging a JavaScript program entails using problem-solving techniques that would impress Sherlock Holmes. Effective debugging of JavaScript requires some experience writing programs for it. After a while, you become familiar with the error messages JavaScript displays and learn ways to solve the errors. Of course, you may not have the time to devote yourself to learning all the intricacies of JavaScript. This column is your quick-reference guide to understanding how to effectively debug JavaScript programs, even without a debugging utility.

Determining the type of error

There are three general types of errors that can occur when playing a JavaScript program. These errors are:

  • Load-time errors
  • Runtime errors
  • Logic errors

Load-time errors are those that are caught by JavaScript as Navigator loads the script. These errors are the major mistakes that prevent the script from functioning before it has a chance to start. It is during the loading process that JavaScript spots any serious errors that will cause your script to fail right off the bat. The script cannot be run until the page has been successfully loaded.

Load-time errors are perhaps the most common and are generally caused by problems in syntax. To help you determine the problem, JavaScript displays a warning box when a load-time error occurs. The warning box tells you the problem and, most of the time, shows you the actual text of the error. Bear in mind that the warning box doesn't always indicate the actual error. Depending on the problem, the error may be located at a different part of the line or even on another line.

As an example, general errors in syntax, such as forgetting to provide the proper open and close braces around a function, create a load-time error. Here's one such example (the actual error message is "missing } after function body"):

function test () {
    alert ("hello")

Even if your script loads without a peep, there is no guarantee that it will run smoothly. Runtime errors are those that occur when the script is actually playing. As with load-time errors, runtime errors are displayed in an alert box. The nature of the error is specified, along with a line number (which isn't always accurate), so you can hunt down the error in the same document.

Where load-time errors are generally caused by mistakes in syntax, runtime errors are most often due to improper use of commands. For instance, you will receive a runtime error if you reference a variable that hasn't been defined. The following results in a runtime error.

Messsage = "This is a test";    // note three s's
document.write(Message);    // note two s's

Another type of runtime error occurs when you misapply one of JavaScript's objects. For example, this code fragment results in an error ("document cannot be set by assignment.") because you cannot assign a value directly to the document object.


Finally, a logic error is when your script does something different than that suggested by logic. The error isn't due to a misplaced parenthesis or misapplied statement, but rather to a mistake in the way you've constructed the script. For example, a logic error occurs if you fail to anticipate the user entering invalid data. The script may fail because the data it processes is not in the proper format.

Common causes of errors

You'll find that most of the errors that beset your scripts are caused by the same, and rather simple, mistakes. Make sure you look for the following:

  • Proper variable names. Keep a sharp eye out for the variables you use and their names. Avoid giving two variables similar names, such as MyVar and MyVal. Avoid one-character differences in variable names, such as Name and Names. And, of course, be sure that the variables you use are spelled properly throughout the script. Remember: JavaScript variables are case sensitive. MyVar is not the same as myvar.
  • Proper function names. Be sure function names are spelled correctly and that they don't have any extraneous characters or spaces.
  • Unique function names. Function names can be used only once in a script (of course you can call a function any number of times). Review all functions to make sure that you haven't duplicated their names.
  • Commas for arguments. With the exception of the for statement (following C and Java practice), JavaScript uses the comma as the separator character for arguments.
  • Proper placement of braces. JavaScript uses the { and } brace characters to define a block of statements. Be sure to include all the necessary brace characters for the statement block or errors will result.
  • Quotes around strings. All strings should have quotes around them.
  • Proper script sequence. It's possible to enter a statement into a script at the wrong place while editing it, especially if you're using time-saving, cut-and-paste techniques. Double check.
  • Correct object names. Be sure names for objects are spelled exactly, and with the proper capitalization. Remember that the built-in objects (Date, Math, Array, Object, etc.) have initial caps; the others start with lowercase letters. Develop a consistent naming convention for your variables, objects, and functions.

Determining the source of a problem

An important step in repairing a broken script is isolating its various functions and routines, and analyzing it on a piece-by-piece basis. This can be done using a number of low-tech approaches, such as setting watchpoints using alert message boxes, and taking advantage of the for/in statement to peer into JavaScript's objects.

More from JavaWorld

Want more programming tutorials and news? Get the JavaWorld Enterprise Java newsletter delivered to your inbox.

Setting watchpoints

Many logic errors are caused by incorrect values in variables. One way to help you spot these logic errors is to set "watchpoints" at one or more spots in the script. These watchpoints are alert boxes that display the contents of the variables. You can also use alert boxes to determine if your code is reaching a certain point in the program. (I use something like alert("to here") to verify the code is working.) Remove the alert watchpoints after the script has been debugged.

Type single-line command entry in the Location box

A little-known JavaScript testing shortcut is to type a JavaScript command line in Navigator's Location box. Preface the command line with the JavaScript: protocol, like that shown below, and press the Enter key to see the result:

javascript:alert ("this is a test")

Note that not all command lines provide meaningful results. For example, typing

javascript:document.write ("this is a test")

and pressing Enter results in true printed in the document window.

If you need to test a number of command lines, you can reduce the keystrokes by typing javascript: (remember the colon) in the Location box. Navigator displays a "JavaScript typein" frame at the bottom of the window. Type the command line you want to try, and press Enter.

Type multiple-line commands using a helper script

The "JavaScript typein" frame window described above is defined within Navigator. You can create your own version of it to allow for simplistic multiple-line command entry (this script is very basic and can be improved, but it serves to get you going). The following displays a multiline JavaScript typein utility. The multiline command entry script is a combination frameset and JavaScript-generated frame document. To use, type the script segment you want to test in the text-area box, and choose Run.

Note: When using this script be sure to append semi-colons (;) at the end of each line. This helps JavaScript properly parse the command lines you enter.

function jsinput () {
parent.MochaInput.document.write ("<b>JavaScript input</b>")
parent.MochaInput.document.write ("<form action=JavaScript: target=MochaOutput>")
parent.MochaInput.document.write ("<textarea name='isindex' rows=5 cols=50>")
parent.MochaInput.document.write ("</textarea><BR>")
parent.MochaInput.document.write ("<input type='submit' value='Run'>")
parent.MochaInput.document.write ("</form>")
<FRAMESET ROWS="50%%,50%%">
<FRAME NAME="MochaOutput" SRC="about:blank">
<FRAME NAME="MochaInput" SRC="javascript:parent.jsinput()">

Make paper copies

JavaScript programs are composed of text embedded in HTML documents. Therefore, you can use any text editor program that has a print capability to make paper copies of your scripts. The paper copies may help you find errors that are otherwise hidden in screenfuls of code displayed on your monitor.

You may find it helpful to print your JavaScript programs in a monospaced font, such as Courier, to help spot such mistakes as a string that is empty but should contain a space. The monospace font is better suited to locating these kinds of errors, but it does takes up more space on the line. Use a small 9- or 10-point font to compensate.

Use a simple object inspector

The for/in statement can be used to create a simple object inspector. A short script is all you need to inspect a JavaScript object. For example, to get a listing of the current properties of the window object, load the script and type window in the prompt box. Choose OK. JavaScript displays an alert box listing each property of the window object.

ret = prompt ("Enter object", "document");
obj = eval(ret);
var temp = "";
for (x in obj)
    temp += x + ": " + obj[x] + "\n";
alert (temp);

Six mistakes everyone makes

Here are a half-dozen of the most common mistakes people make when writing JavaScript programs. These are listed in no particular order.

1. Missing quotation marks for strings

This should go without saying, but I'll say it anyway: Remember to provide quotes (either single or double) for all strings. The obvious use -- and most common site of abuse -- is the document.write method.

document.write(<H1>This is a heading</H1>);

This will cause a load-time error when the browser tries to load the script, because quotes are missing within the document.write statement. JavaScript doesn't know quite what's wrong here; it just tells you there's a syntax error and leaves it to you to figure out what's wrong. Add quotes to fix.

2. Mismatching quotation marks

JavaScript lets you use the single quote (') or the double-quote (") to delineate strings. However, you must be careful to stick with the same type, or else JavaScript will render an error message. The following is not allowed, because the characters used for the quote symbol are not consistent.

document.write("<H1>This is a heading</H1>');

JavaScript lets you "embed" a quoted string within another. In this case, you will want to use both quote types. However, keep in mind that for every type of quote that starts the string, you must have a matching end quote. Here's an example. Notice that the entire string is enclosed in single quotes, and the "internal" string is enclosed in double quotes. The result is a heading that appears as Ways to "Improve" Your JavaScript Programs.

document.write('<H1>Ways to "Improve" Your JavaScript Programs</H1>');

3. Using single equals instead of double equals in comparison expressions

This mistake is so common (unless you're a dyed-in-the-wool C programmer) you're bound to do it at least once. JavaScript expects to see two equals signs in a comparison expression, not one. This is a mistake:

if(MyVar = "xyz")

4. Referencing objects that don't yet exist

Navigator processes a page in the order it receives its HTML markup. It is common to place JavaScript code at the beginning of the page (usually in the <HEAD> tag). This can lead to errors if you attempt to reference some other part of the page that hasn't been loaded. For example, the following JavaScript attempts to reference a form control when the page is loaded. This reference comes before the control has been defined, so an error occurs.

1 2 Page 1
Page 1 of 2