A Survey of Data Display in JavaScript Debuggers

History

Introduction

I thought it would be interesting to compare the methods used to display data in JavaScript debuggers. I surveyed:

I suppose I should test Internet Explorer as well, but I don't think I have the requisite tooling installed to use the debugger (if someone wants to contact me offline about how to set up IE for debugging without having a for-pay version of Visual Studio installed, please do).

I also included Eclipse's Java debugger in the survey.

For the test, I constructed an HTML file with some JavaScript code that created a set of data, and then compared how this data was displayed in the various debuggers.

The Data

The data used in the tests was constructed as local variables within a function which was programmatically invoked. Note, this paper includes a link (below) to run the test.

First a set of basic objects is created:

    var anInteger        = 42;
    var aFloat           = 6.66;
    var aBoolean         = true;
    var aString          = "Lorem ipsum dolor sit amet,..."; // 180 chars total
    var aNull            = null;
    var anUndefined      = undefined;
    var aNaN             = 1/undefined;
    var anObject         = {x: 5, y: 25};
    var aPrintableObject = {x: 5, y: 25};
    var aMap             = {};
    var anArray          = [];
    var anArguments      = arguments;
    var anElement        = document.getElementById("body_title")    

Then, the aMap object has a number of properties added; a property with the name of each of the variables above is added, with the value being the variable's value. Then, the anArray object has a number of elements added; each of the variable's value above is added to the list. The aPrintableObject object is augmented with a toString() method which displays the values of it's properties.

For Java, a method similar to this function is created as a static main for a class.

Note that initial attempts at creating recursive versions of anArray and aMap by adding those objects to themselves resulted in "odd behavior" in some browsers and even the Eclipse debugger. This should be further investigated, but for the purposes of this exercise, the immediately recursive structures were not used.

To run the test yourself, bring up the JavaScript debugger for your browser, and then click here. Because there is a debugger statement in the run() function which is invoked, you typically won't need to set a breakpoint to get to the point where all the variables are set, however, you will likely need to display and/or enable the debugger before traversing the link.

JavaScript source: test.js

Java source: Test.java

Initial unexpanded variable list

This is the list of variables that the debugger initially displays when it hits the breakpoint.

Notes:

Though it's not displayed, expanding the aMap variable results in a sublist for each of the debuggers which is similar to this list itself. For Eclipse, well, let's not go there.

Firebug

Web Inspector

Dragonfly

Eclipse

aPrintableObject expanded

In this set of images, we see the aPrintableObject expanded.

Firebug

Web Inspector

Dragonfly

Eclipse

anArray expanded

In this set of images, we see the anArray variable expanded. No big surprises based on anything we've so far. Except that Web Inspector appears to be sorting the key names alphabetically, which is confusing.

Firebug

Web Inspector

Dragonfly

Eclipse

anElement expanded

The main point in showing this set of images is to demonstrate how generally useless it is. Rather than display a large number of nested value whose values, it might be nice to optionally filter this list somehow.

Firebug

Web Inspector

Dragonfly

Eclipse

REPL

Each of the JavaScript debuggers supports a REPL in some form. For this set of images, I sequentially evaluated the variable names aMap, anArray, and anElement.

The results are pretty much what we would expect given what we've seen so far, with some surprises.

Firebug

Web Inspector

Web Inspector with expanded Object

Dragonfly

Summary / Thoughts

As noted, Firebug has a bug or two to work out, but is considered the gold standard of JavaScript debuggers. Primarily because it's the only debugger that developers even realize exist today. But it also currently wins on features alone, including:

Dragonfly is the newest of the debuggers, and has some room for growth. Once some of the styling issues are resolved, it really just needs to add toString() representations where appropriate.

Web Inspector could make use of styling data types ala Firebug and Dragonfly, adding toString() representations where appropriate, and it will then be pretty much up-to-snuff.

General issues concerning all the debuggers is dealing with objects which you'd like to see different representations. Web Inspector and Firebug both display nice renderings of HTML elements, but only in the console. And frankly, this is too browser specific. Need to think wider, as more folks start to look at using JavaScript on the server. How can we accommodate application- or user- specific renderings for objects to make debugging that much nicer of an environment.

One feature I didn't show was Eclipse's Detail Formatters. A Detail Formatter provides a runtime override of the toString() method for a particular class. These are stored persistently in your workspace, so you don't need to edit them every time.

This feature is nice, as it allows you to extend runtime behavior just while debugging - no code was harmed or edited while debugging. Such a feature would be nice to provide for JavaScript as well.