Channels ▼
RSS

Debugging JavaScript


WebReview.com: Debugging JavaScript

Rank: 3

Things You'll Need

Copy and paste to a file and name debugbegin.html.

Code Sample (after): Copy and paste to a file and name debugfinal.html.

Graphic Files: Download in .zip format.

Graphic Files: Download in .sit format.

Instructions:

Once you have the files you need, place the script files in a folder. Then, create a subfolder called "images" and unzip or unstuff the images to that folder. Test in your browser, and start debugging!

Whether you are cutting-and-pasting pre-written scripts, just starting out in writing your own, or are a seasoned JavaScripter, you probably have to spend a lot of time troubleshooting and debugging. I've found that this part of the scripting process can be challenging regardless of your level of JavaScript experience. To make life easier, here are some fundamentals of debugging and a few troubleshooting steps just for you.

Understanding Different Types of Errors

There are three basic types of errors in JavaScript, or any other programming or scripting language for that matter. They are Syntax errors, Runtime errors, and Logical errors. Whenever you're troubleshooting a script, try to look for errors in that order, starting with Syntax errors. It's also important to know what each of the error messages mean.

  • Syntax errors in client-side JavaScript are usually one of the following: typos, spelling mistakes, missing quote marks, missing/unmatched brackets, or missing object names or IDs. Remember that JavaScript is usually case-sensitive: "someObj" is not the same as "someobj". The majority of script errors are caused by incorrect syntax. Luckily, these are also the easiest to spot.


  • Runtime errors are illogical or incorrect reasoning in your script. A very common error in JavaScript is mismatched data types—something like trying to perform a mathematical calculation on a data string. (The ubiquitous "...is NaN" message signifies this type of error.)


  • Logical errors are errors which won't show up as error messages, but are nevertheless not what you want from the script. For example, if you mouseover one button that you want highlighted, but instead another one changes color, that's a logical error.

Getting a Programmer's Text Editor

All too often I see people struggling to hand-code in a plain text editor like Notepad or SimpleText. Yes, you can write code with them. But why make your life harder when there are so many free or inexpensive text editors available? Even if all you want to do is hack other people's scripts, you'll need a text editor. And most of these text editors also make your HTML coding tasks easier, too. A good text editor should offer these features:

  • Line numbering. Any error messages that your browser returns will refer to a line number. Even though this number is often wrong, in most cases it will at least point you to the general area where the error can be found. Note that if you have external linked JavaScripts, Microsoft Internet Explorer will not know which line to point to at all and will most likely just point at the <body> tag. In this case, try pasting your external script back into your HTML document to debug it. You can always dump it out into an external document once your script is working.


  • Color-coded syntax. This feature can save countless hours, since it helps you quickly spot obvious errors such as missing quotation marks. You will need a text editor that recognizes JavaScript syntax.
  • The screenshot here shows how useful this can be. With color-coding, it's easy to spot a syntax error—in this case, a missing quotation mark.

    color-coded syntax
    Figure 1: Color-coded syntax is easier to debug.

  • Parentheses balance. One of the most common errors in JavaScript is missing parentheses. In an editor like BBEdit for example, when you type a closing parenthesis, the matching one higher up in the function will be highlighted. This is very useful when you have a lot of nested conditional statements, and you are trying to figure out what ends where.

Programmer's editors are easy to find. In fact, Web Review's David Mertz writes an ongoing series on programmer's editors, which you can find detailed on his bio page.

Using Netscape 4's Built-in JavaScript Debugger

Those cryptic JavaScript error messages in MS Internet Explorer, or Opera 4, for that matter, such as "Object Expected" or "Undefined Function" are rather unhelpful. In Netscape Navigator or Communicator 4.x, you will also see the even less helpful "JavaScript error" in the status area while your page stops dead in its tracks. But the built-in JavaScript debugger can pinpoint many common errors, especially the most obvious syntax errors. To invoke it, just type "javascript:" (without the quotes) in the location of your Netscape browser. This will open a debugging console window that shows all of your most recent JavaScript errors. To clear the console, just click the "Clear" button. Besides running your code, you can also type or copy/paste commands directly into the debugger text area. (Note: Mozilla/Netscape 6 doesn't have this built-in debugger yet.)

Here is a screenshot of a portion of the Netscape 4 debugger:

javascript console
Figure 2: Using Netscape 4's JavaScript debugger.

Making it Simple

Sometimes, you may slowly build up a function, until you have lines and lines of code, with many nested conditional statements, and then completely lose track of what you're doing. The best way to retrace your steps is to comment out pieces of your code until you get back to a place where things are actually working. The term commenting out means placing special characters at the start of a line or around a piece of text, so that the script skips over it.

There are two ways of adding comments to JavaScript: Putting two slashes // at the beginning of a line or a portion of text, or surrounding your comments with /* and */. I recommend using the second method for all but the shortest bits of text, since sometimes the browser will wrap the text at an arbitrary place in your line. You can comment out whole chunks of nonworking text simply by surrounding it with /* */.

Inserting alert()s at Key Places in Your Script

Frequently, when you check the actual value returned for a variable or an object that you are referencing, you can see what is going wrong in your function. In order to check key values at various points in your code, an easy thing to do is to use the alert() method.

A typical alert inserted into a buggy piece of JavaScript might look like this:

var myVar = "Three Stooges";
var mysum = 5 + 3;
var myObj = document.button;
alert('the value of myVar is '+ myVar + ' and the value of 
mysum is ' +mysum+ ' and the value of myObj is '+myObj);

This is how the message in the alert window might look:

the value of myVar is Three Stooges and the value of mysum
is 8 and the value of myObj is [obj IMG]

The third variable (obj) denotes an Object on the page, and the second part of the text lets you know what kind of object it is (such as IMG, DIV, or LAYER for Netscape). If the object you are looking for is missing, you will get an "undefined" message—which tells you that you have either forgotten to name an object on the page, forgotten to put it into your HTML at all, or are addressing it improperly for that particular browser. This last problem can be a real show-stopper for new JavaScripters dipping their toes into CSS + JavaScript.

When you insert an alert, it's always a good idea to put a string in front that describes the alert, as in the above example. Otherwise, when the alert pops up, more often than not you'll forget what it is you're supposed to be looking for!

Making Your Own Debugging Console Window

Both Microsoft and Netscape have JavaScript debuggers that run within their respective browsers. The Netscape debugger is a Java application, and the Microsoft one only runs on Windows. However, I have never found them to be that useful for pinpointing the problem areas in a meaningful way.

Instead, I create my own "debugging console window". This simply means creating a new child window (commonly called a "popup window"), to which you can write any variables or the values of objects. And you can use the "console window" to write one value, or any number of values.

This method is useful not only for debugging the obvious errors such as syntax errors, but also for checking the logic of your script.

Here is a simple way to create a new child window:

function debugConsole() {
    debugWindow = window.open
("","debugWin","toolbar=no,scrollbar=yes,width=300,
height=400");
}

This will open a simple small window with no toolbar and a scrollbar, ready to accept your debugging. You can also just open a window with the javascript: protocol directly in the link too. If you use this method, you may want to specify javascript:void to ensure your original window does not change. Since I prefer to keep my JavaScript separate from my HTML body as much as possible, I generally use the above function.

var myVar = "Three Stooges";
var mysum = 5 + 3;
var myObj = document.button;
debugWindow.document.writeln('<html><body>');
debugWindow.document.writeln('the value of myVar is '+ myVar + '<br />');
debugWindow.document.writeln('the value of mysum is ' +mysum+'<br />');
debugWindow.document.writeln('the value of myObj is '+myObj+'<br />');
debugWindow.document.writeln('<\/body><\/html>');

The line break at the end of each writeln statement is to make each statement show up on a separate line. Add meaningful comments to your writeln statements to indicate what you are checking for! Also, with any document.write statements, be careful to escape any special characters such as / or quotation marks, by placing a backslash \ in front.

While for only checking 3 values as above, you can get by with using the alert() method, the big advantage of writing values to the separate window is when you have multiple values to check, such as an array, or a looping statement. We have written JavaScript functions for example that generated about 6,500 array items. You can well imagine that using the alert() method for debugging this kind of function is very impractical, not to mention annoying!

Putting it All Together

To illustrate the steps I've listed, I have created a page with a simple rollover script. There are two versions: the original nonworking version—which is full of some typical syntax, runtime and logical errors, and a bug-free working version. As an exercise, see if you can de-bug the first version and get it working! When you're done the script should work in all the major browsers. Links to both scripts, and the necessary images you'll need, are available in this article's sidebar.

You Will Always Have to Debug

No matter what you're writing JavaScript for—from the simplest scripts to the most advanced DHTML effects—debugging is sure to eat up a good amount of your time. Hopefully, some of these debugging tips will help make your scripting work more efficient, and maybe even a little fun.


Maki is a graphic designer and illustrator for both print and on-screen applications. She is also experienced in Javascript for HTML and DHTML/CSS.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video