USING THE NETSCAPE JAVASCRIPT DEBUGGER

By Angus Davis

Send comments and questions about this article to View Source.  

Netscape JavaScript Debugger is a new tool that makes writing applications in JavaScript much easier. Using this tool, you can debug scripts as they run, determine what's going on inside your script at any moment, and find problems quickly. For an excellent overview of other debugging principles, see Danny Goodman's recent article Advanced JavaScript Debugging Techniques

A debugger controls the environment in which programs run. It differs from a development environment where you write code for applications, or from a compiler or interpreter that allows source code to actually run on a machine. In Netscape Communicator, the JavaScript interpreter handles execution of scripts written in JavaScript; you can think of the JavaScript Debugger as the interpreter's remote control, which allows you to stop, start, and ask the interpreter questions about its state. (Currently, the preview release of Netscape JavaScript Debugger does not permit debugging of server-side JavaScript.)

I used Netscape JavaScript Debugger recently while writing a small crossware application that helps build Netcaster channels. Although I had never used any scripting debugger before, I picked up on the essential features quickly. In the end, using the debugger made my development process much easier, as the time required to complete my project was reduced by about 25 percent.

In this article, I'll outline the uses and features of Netscape JavaScript Debugger. So that you can follow along with the examples I provide, make sure you're running Netscape Communicator 4.01 for Windows 32-bit platforms or Power Macintosh. You'll also need to have preview release 2 of Netscape JavaScript Debugger and know how to launch it. (This preview release will not run on Windows 3.1, Macintosh 680x0 models, and UNIX versions of Communicator other than Solaris 2.4 and 2.5, IRIX 5.3, 6.2, and 6.3, and SunOS 4.1.3.)

The quick overview contained in this article is by no means a comprehensive examination of debugging features. For a detailed look at Netscape JavaScript Debugger, see the online documentation, Getting Started with Netscape JavaScript Debugger.

A REMOTE CONTROL FOR THE JAVASCRIPT INTERPRETER

It's easy to understand Netscape JavaScript Debugger as a sort of remote control for Communicator's JavaScript interpreter. There are essentially three things the remote control can do to the interpreter: stop, start, and inspect.

By using more complicated features such as conditional breakpoints, you can precisely control when code execution should stop and where it should begin. This allows you to stop programs as they are running at the click of a button, or when a certain condition is true.

By evaluating variables and monitoring the call stack, you're able to inspect what's going on inside the interpreter at any moment. The JavaScript Debugger reflects the interpreter's state, giving you a better understanding of your application's inner workings.

In the sections that follow, I'll look at ways to use Netscape JavaScript Debugger as a remote control for stopping, starting, and inspecting JavaScript applications. At this point, you should fire up your JavaScript Debugger if you haven't already, so that you can follow along with the examples.

SETTING INTERRUPTS

Just as Netscape Navigator's Stop button arrests the loading of a web page, Netscape JavaScript Debugger offers several ways to stop JavaScript applications that are running. Typically, you stop an application to inspect its state.

For the purposes of this article, I've created the following simple JavaScript clock that is supposed to display the current time every 1000 milliseconds to a form field in an HTML document: 

<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
var now = null;
function updateTime() {
    now = new Date();
    document.clock.display.value = now.getTime();
}

</SCRIPT>
</HEAD>
<BODY onLoad="setInterval(updateTime,1000);">
<FORM NAME="clock">
<INPUT NAME="display" TYPE="TEXT" SIZE=50>
</FORM>
</BODY>
</HTML>
When I run this script to see it in action, however, I don't get what I envisioned. Instead of seeing the current time displayed in the traditional "12:00:00" fashion, I get a confusingly large number. The JavaScript interpreter in Netscape Communicator is actively running this code, diligently firing off the updateTime() function every second, but the odd number that appears in the form field looks nothing like the current time.

In this scenario, it makes a lot of sense to use Netscape JavaScript Debugger to take a look at what's going on inside the application. The first step is to click the Interrupt button in the debugger while the clock program is running. 

Once code execution is interrupted, the debugger comes to life, indicating the current state of the call stack by highlighting the source code in use and reflecting the name and position of the function in the call stack pane, as shown in Figure 1.


Figure 1. An interrupt

My next step is to evaluate the current time by highlighting now.getTime() and clicking the Evaluate button. When I click this button, the value returned by now.getTime() appears in the debugger's Console pane, and again I see the rather odd-looking large number, as shown in Figure 2. 


Figure 2. An evaluated expression

At this stage of the debugging process, I've narrowed down the problem with my JavaScript code to the getTime() method. With a quick check of Netscape's JavaScript Guide, I learn that the getTime() method is designed to return the current time, all right -- as seconds since 1970!

After a bit of reading, it becomes clear that in order to generate the desired "hours:minutes:seconds" output, I'll probably need to use the getHours(), getMinutes(), and getSeconds() methods instead of getTime(). My hypothesis is that the following code should be just what the doctor ordered:

now.getHours()+":"+now.getMinutes()+":"+now.getSeconds();
Before rewriting my program code, I can test my hypothesis: I type this line of JavaScript code directly into the debugger's Console pane. When I press the Enter key, the debugger automatically evaluates the expression I've typed. Figure 3 shows the Console pane with the evaluated line of JavaScript code I typed in.
      
Figure 3. The Console pane

Now that I've identified the problem and tested a solution, I can update my JavaScript code to reflect the changes.

While this is a good example of Netscape JavaScript Debugger's ability to interrupt and inspect an active JavaScript application, there are some more powerful features to investigate.

SETTING BREAKPOINTS

A breakpoint is a location where program execution automatically halts. Using Netscape JavaScript Debugger, you can place breakpoints anywhere in your code. When the breakpoint is encountered by the JavaScript interpreter, program execution stops immediately, as though you had clicked the Interrupt button.

Breakpoints are useful if you'd like to inspect the inner workings of your program at certain predefined points. For example, if you have a complicated form-processing application that calculates totals, you can place breakpoints in functions to determine the values of various elements as the form is processed.

Suppose I want to set a breakpoint in the JavaScript code for my familiar clock script:

<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
var now = null;

function updateTime() {
    now = new Date();
    document.clock.display.value =
now.getHours()+":"+now.getMinutes()+":"+now.getSeconds();
}

</SCRIPT>
</HEAD>
<BODY onLoad="setInterval(updateTime,1000);">
<FORM NAME="clock">
<INPUT NAME="display" TYPE="TEXT" SIZE=50>
</FORM>
</BODY>
</HTML>
By setting a breakpoint at the proper place in this code, I could stop the code execution anytime the updateTime() function is called. Although this isn't entirely useful in a simple program like this clock example, it demonstrates how you can use the breakpoint feature in larger, more complex programs that would be too lengthy to include in this article.

To set a breakpoint on the updateTime() function, I select the first line of the function, as shown on the left in Figure 4. Next, I click the debugger's Breakpoint button. A red dot appears next to the first line of the function indicating a breakpoint, as shown on the right of Figure 4. 


Figure 4. Setting a breakpoint
 
 

Traditional breakpoints are "dumb," in that they always stop the code execution at a certain point, regardless of the program's state. However, Netscape JavaScript Debugger also supports conditional breakpoints -- a special type of breakpoint that is "smart" by comparison.

Using conditional breakpoints, you can set a condition to determine whether the code execution stops at a given point. A condition is a statement that, when evaluated, returns a Boolean value of true or false. You can think of a normal, unconditional breakpoint as a conditional breakpoint whose condition always returns true

To set a breakpoint's condition, I select the line of an existing unconditional breakpoint and choose Edit Breakpoint from the Control menu. The Breakpoint Condition dialog box appears, as shown in Figure 5. 
      


Figure 5. The Breakpoint Condition dialog box

In this dialog box, I specify the breakpoint condition. If I specify an invalid expression as the breakpoint condition, it will be ignored by the interpreter. A conditional breakpoint only halts execution when the expression returns true (that is, it doesn't work for 1, 0, and so on).

USING WATCHES

Sometimes you may want to keep an eye on a set of conditions inside a program. I've often done this using various approaches, such as printing information about these conditions to a window's status bar or setting an alert to fire off every so often, notifying me of the current status of the variables I'm interested in.

Using Netscape JavaScript Debugger, it's possible to specify a set of variables or expressions to monitor. Any time the JavaScript Debugger is invoked, it automatically evaluates the current value of these expressions in the Watches window. 

Let's assume that I'd like to watch the time in my clock script. With that script loaded in the JavaScript Debugger, my first step is to open the Watches window by choosing Watches from the Edit menu.

The Watches window appears, containing a New button that allows me to add an expression or variable to the list of watched items. For this example, I've chosen to monitor the value of now.getSeconds(), as shown in Figure 6. If I ever interrupt the script while this code is executing within the updateTime() function, the value of the current time's seconds field will appear in the Watches window.


Figure 6. The Watches window

Note that monitored values ("watches") update only when you interrupt the program execution (by using the Interrupt button or breakpoints). Watches do not dynamically update as the script is running. 

PUTTING IT ALL TOGETHER

The examples I've outlined here are so simple they border on being ridiculous -- in such simple test cases, debugging is not always necessary. However, in large and complicated projects, such as those that handle complex form validation or Dynamic HTML control, JavaScript code can grow to be very lengthy and complicated. Netscape JavaScript Debugger makes it easier to find problems in your code for these types of projects, and saves a fair amount of time in the process.

Another useful application for the debugger is in helping to manage server-side JavaScript (formerly LiveWire) projects. While this feature of Netscape JavaScript Debugger is not yet implemented, it undoubtedly will be a powerful ally in your development efforts when it becomes available.

It's now up to you to use the JavaScript Debugger and provide Netscape with feedback about how to make it better. Use the Netscape JavaScript Debugger newsgroup for your suggestions. And be sure to let View Source know if you have any questions or ideas about this article.


View Source wants your feedback!
Write to us and let us know
what you think of this article.

Angus Davis is a Technology Researcher with Netscape Communications. He recently finished an internship with View Source and is now working in Netscape's Technology Group. Angus enjoys skiing, sailing, and movies during the two hours each week Mozilla lets him out of the net-cave. Before coming to Netscape, Angus worked at IDS in his home state of Rhode Island. Angus' geek code is: "GO d+ s: a19 C+ U P+ L E---- W+++ N+ w--- V PS PE++ Y+ t- X  tv+ b+ DI++ D G e h r++".


Copyright © 1997 Netscape Communications Corporation