Debugging JavaScript

Introduction

In this tutorial we will look at techniques for debugging JavaScript code. First we'll look at how to use the error console. Then we'll see how to use the alert and console.log functions to display debugging information. Finally, we'll see an introduction to the Chrome developer tools.

This tutorial focuses on using Chrome because Chrome is a popular browser available on Windows, Mac and Linux, and it has built-in developer tools. Safari and Firefox also have good developer tools. Here are some links to information about developer tools in various browsers:

Chrome developer tools: https://developer.chrome.com/devtools

Firefox developer tools: https://developer.mozilla.org/en-US/docs/Tools

Safari developer tools: https://developer.apple.com/safari/tools/

Learning how to use your browser's development tools is very important. I recommend that you learn how to use them now, with simple programs, so that later on when you're working on larger programs you will already know how to use them.

The error console

The simplest debugging tool to use is the error console that most web browsers provide. If your JavaScript code doesn't do what you expect it to do, open the error console and see if there are error messages.

In Chrome, you can get to the error console by using the Chrome menu button (three horizontal lines), and then choosing More Tools and then JavaScript Console as shown in the following image.

The image above shows the keyboard shortcut for opening the JavaScript console on a Mac (which is option-command-J). The keyboard shortcut for Windows is control-shift-J. See https://developer.chrome.com/devtools for more information.

Here is an example of an error message which resulted when I changed alert to alarm:

The error button below generates a JavaScript error (calling the function foo, which is undefined), so you can see how your browser shows error information.

Even though the error console is relatively simple to use, it's very important. Unlike compiled languages, like C++, Java, and C#, JavaScript does not have a compiler that notifies you about errors in your code. Instead, you need to know how to use the error console so that when problems occur you can find out what's going on.

The alert method

Another easy-to-learn debugging technique is using the alert method, which will show a dialog box with debugging information. For example, if you want to see what the value of the variable x is at a certain point in your program, you can use a JavaScript statement like this:

alert("x is: " + x);

Click this button to see an alert:

Although alerts are easy to write and use, they don't work well when you need to see more than two or three values. For example, if you have a loop in your program that executes 100 times, you wouldn't want to click on an OK button 100 times, which is what you'd have to do if you use an alert in the body of the loop. Also, once you click on the OK button there's no way to go back and look at the information again.

The console.log method

An alternative to using an alert dialog box is to use console.log to write debugging information to the JavaScript console. To see what the value of the variable x is you could use a statement like this:

console.log("x is: " + x);

The button below will print a message to the console. Open the JavaScript console in your browser, and then click the button and see how the message is displayed in the console.

Here's an image of how that showed up in Chrome:


With console.log, you don't have to click on the OK button each time information is displayed, and your debugging information stays in the console until you clear the console.

console.log is non-standard and should not be used in production web applications, but it is very useful for debugging and testing.

The innerHTML property

The innerHTML property can be used to modify the contents of an HTML page after the page has been loaded. You can create a div (or other suitable HTML element) on your page that is specifically for debugging and write code that adds debugging information to the div where you can easily read it. When you are finished debugging the code you can remove the div.

Click on the random button below to see how the contents of the div (with the yellow background) change. The JavaScript code that is executed when the button is clicked chooses a random number in the range 1 to 20 and displays it in the yellow div.

Debug information will replace this text.

The button's onclick event handler calls the writeDebug function which is shown below. writeDebug uses document.getElementById to get a pointer to the div where debugging information will be displayed, and then uses the innerHTML of the div to replace the contents of the div with the string that is passed as a parameter to writeDebug.

function writeDebug(debugStr) { var debugDiv = document.getElementById("debugDiv"); debugDiv.innerHTML = debugStr; }

The function shown above replaces the contents of the debug div with its parameter. Often it's useful to add the parameter string to the end of the debug div so that all of the debugging information can be seen.

debugDiv.innerHTML += debugStr + "<br>";

The Chrome debugging tools

A video presentation of this section is available here.

The next debugging technique that we will look at is the Chrome debugging tools. The debugging tools allow the programmer to set breakpoints and watches in the program and to step through the program to see what's happening.

For sample code to demonstrate the debugging tools, I wrote JavaScript code to draw a box like the following one in an HTML element.

***********
***********
***********
***********

We'll look at a script that draws a rectangle 20 stars across and 10 stars high. The code is in a file named box.js. You can see an HTML page that uses that code to draw a box here: box.html

function drawBox() { var i, j; setHTML("outputEl", ""); // CLEAR THE OUTPUT ELEMENT for (j = 0; j < 10; j++) { for (i = 0; i < 20; i++) { addHTML("outputEl", "*"); } addHTML("outputEl", "<br>"); } } setClickHandler("drawBoxBtn", drawBox);

This code uses three functions that are defined in a different file: setHTML, addHTML, and setClickHandler. You can see the definitions of those functions in the file gui.js

setHTML takes an element id and an HTML string as paramters and sets the innerHTML property of that element to be the second parameter.

addHTML has similar parameters, but appends the HTML string to the innerHTML of the element instead of replacing what's already there.

setClickHandler takes an id of an HTML element as its first parameter and a function as its second parameter. It sets the onclick event handler of the element (specified by the id passed as the first parameter) to be the function passed in as the second parameter.

In the HTML document there is a div that has outputEl as its id. The call to setHTML clears the output element by setting its innerHTML property to be an empty string.

The code that draws the box of stars has two nested loops. Each time through the inner loop, one star is added to the current line by calling addHTML. Each time through the outer loop, one line of twenty stars will be drawn by the inner loop. Then a break tag is added to the innerHTML of the div by calling addHTML again. Adding a break tag to the innerHTML is similar to printing a newline in a C++, Java, or C# console program.

In the Chrome debugging tool I will set a breakpoint on the second call to addHTML. I will also put a watch on the variable j. Then I will step through the code and see the value of j change each time through the outer loop.

Breakpoints are useful because they allow the programmer to pause execution of the program and inspect the values of variables to see what is happening in the program. A watch allows the programmer to easily see how the value of a watched expression changes as the program executes.

To set a breakpoint, I first need to select the file with the JavaScript code I am debugging. At the top of the developer tools panel (or window) is a set of tabs that say Elements, Network, Sources, etc. For debugging JavaScript code, click on the Sources tab. In the left pane, you'll see the files for the web application. In this case the files are box.html, box.js, and gui.js. I'll click on box.js to select that file. When I do, the debugger shows the source of the file in the middle pane, as shown in the image below.


Now I can click on the line number for the line where I want to set a breakpoint. Breakpoints are shown by blue arrows. To set a watch on a variable, I can click on the + button on the right of the Watch label in the right-hand pane. When I click on the + button, I can type in an expression to watch. I'll enter j to create a watch on the variable j.

Here's what the debugging window looks like after I have set a breakpoint on line 10 and put a watch on the variable j:


I'm ready to debug the program, so I click on the draw box button to execute the JavaScript code for the drawBox function. The first line of stars is added to the output element, and then execution stops at the line with a breakpoint. The debugger highlights the line of code that is about to be executed in blue. In the pane at the right, I can see the current value of j, which is zero.


Note that there are several places where I can see the value of the variable j: in the yellow boxes the debugger adds to the source code, in the Watch box, and in the Scope Local box.

When I want to continue execution I can use the bottons at the top of the right pane:

Clicking on the button on the left (blue box and triangle button) will continue execution until the next breakpoint is reaced and then pause again. Clicking on the curved arrow button will step over the next function call and then pause after returning from the function. Clicking on the down arrow button will step into a function (pause on the first line of the function). Clicking on the up arrow will step out of a function (finish executing the current function and then pause when it has finished).

If I hold the mouse button down over the blue box and triangle button, I can choose a button that is a blue triangle. Clicking the blue triangle button will continue execution and ignore breakpoints.

Summary

These are the JavaScript debugging techniques that we've seen: