Locating Bugs in Your Javascript Code

If you’re anything like me, you have traditionally used javascript alert boxes to try to identify and diagnose bugs in your javascript code. There are two major issues with this process, though.

  1. It’s extremely inconvenient for your users if you’re trying to debug a live application.
  2. It can be a real problem if you end up in some sort of long/infinite loop and end up outputting multiple alert boxes.

There is a better way, though, and it basically works in Internet Explorer (version 8), Firefox (with the Firebug extension installed), Chrome, Safari and Opera. This is nothing new, by any strecth of the imagination, but it still seems to be a bit of a well-kept secret for a lot of developers.

To debug your applications without hassling your users, you can use the “console” to “log” information from your script, rather than trying to use alert boxes all over the place. There are a few caveats of which to be aware when using the console, though.

First of all, it’s not implemented in exactly the same way in each browser. For instance, although the console is installed by default with IE8, it is only enabled (and therefore, only “exists”) when the “Developer Tools” window is open. The console (in this sense of the word) doesn’t exist at all in Firefox unless Firebug is installed.

Unfortunately, if the console doesn’t “exist”, an error will occur in your javascript if you try to access it for any reason. Therefore, before you actually try to use the console, you should check to make sure it’s defined.

To use the console logging feature, you should wrap it in an “if” statement checking to make sure the console is defined, first. That would look something like:

if(typeof(console) !== 'undefined') {
	console.log('This is a test');
}

Another issue with the slightly inconsistent implementation of the console between browsers is the way variable/object information is output to the console. Webkit browsers (Chrome and Safari) and Firefox will display all the information there is to display (property names, property values, events, etc.) about a javascript object, and will do so recursively (meaning that, if an object contains another object, all information about that inner object will be displayed as well). However, Opera and IE only indicate that the object is, in fact, a javascript object, and will usually indicate the “type” of object (if the object has a specific type). Of course, that doesn’t do you much good if you’re trying to do something like compare a DOM element’s “id” attribute to its “name” attribute, as you will need to log those two items separately, rather than just outputting the DOM object to the console.

Finally, Opera and IE will use a persistent log (once the log is open, it doesn’t get cleared until you manually clear it or you close the browser) when using the console. Firefox/Firebug can be set to allow the log to persist by simply clicking the “Persist” button in the Firebug Console. Chrome and Safari will automatically clear the log every time you move to a new page or refresh the current page.

While the log-clearing can be nice to keep you from getting confused as to when the output was generated, it can also be frustrating if you’re trying to track the way an object changes from page to page. For instance, I had a page that should have been loading information via AJAX, but, instead, was simply going to the target of the link. When trying to debug the problem in Chrome, the console kept getting cleared when the browser moved onto the target of the link, so I couldn’t get any useful information as to why the AJAX portion of the script was failing to stop the default link event from firing. In that case, I ended up setting some breakpoints in my javascript to see if I could catch where the issue was happening, but I could have also tried to debug the issue in Firebug with the “Persist” feature enabled.

Ready to do some testing on your own? Here is some very simple code that creates a new javascript object with multi-level properties and then outputs that object to the console. Open up a few of the browsers you have installed and try it out. See what kinds of results you get. You can even remove the “if” statement that wraps the console.log() function and see what happens in your browsers.

<script type="text/javascript">
var testObj = {
	"param1":"value1",
	"param2":{
		"innerp1":"innerval1",
		"innerp2":"innerval2",
		"innerp3":"innerval3",
		"innerp4":{
			"thirdlevel1":"thirdlvlval"
		}
	},
	"param3":["arrayval1","arrayval2","arrayval3"],
	"param4":"value4",
	"param5":{
		"innerp5":"innerval5",
		"innerp6":"innerval6"
	}
}
if(typeof(console) !== 'undefined') {
	console.log(testObj);
}
</script>

I hope, at this point, you can see just how useful this can be.