9

I'm aware of console.log in firebug, and this thing called dbug (but not at all what I want). What I'm looking for is something that will give me a pretty print nested view into an object that looks like this for javascript:

dbug output
(source: ospinto.com)

I'm also aware of this question, and am looking for something a little more tabular.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
cgp
  • 41,026
  • 12
  • 101
  • 131
  • 2
    Interesting question, though I wonder how such a pretty printer would work for circular references... – Dan Lew Jun 03 '09 at 20:23

4 Answers4

5

An attempt:

See a demo: http://jsbin.com/oxeki

The code:

var prettyPrint = (function(){

    var htmlObj = function(obj){
            if (Object.prototype.toString.call(obj) === '[object RegExp]') {
                return obj.toSource ? obj.toSource() : '/' + obj.source + '/';
            }
            if (typeof obj === 'object') {
                return prettyPrint(obj);
            }
            if (typeof obj === 'function') {
                return document.createTextNode('function(){...}');
            }
            return obj.toString();
        },
        row = function(cells, type){
            type = type || 'td';
            var r = document.createElement('tr');
            for (var i = 0, l = cells.length; i < l; i++) {
                var td = document.createElement(type);
                td.appendChild(typeof cells[i] === 'string' ? document.createTextNode(cells[i]) : cells[i]);
                r.appendChild(td);
            }
            return r;
        },
        heading = function() {
            var thead = document.createElement('thead');
            thead.appendChild(row(['Name','Value'], 'th'));
            return thead;
        };


    return function(obj) {

        var tbl = document.createElement('table'),
            tbody = document.createElement('tbody');

        for (var i in obj) {
            var objCellContent = obj[i] === obj ? document.createTextNode('CIRCULAR REFERENCE') : htmlObj(obj[i]);
            tbody.appendChild( row([document.createTextNode(i), objCellContent]) );
        }

        tbl.appendChild(heading());
        tbl.appendChild(tbody);
        return tbl;

    };

})();
James
  • 109,676
  • 31
  • 162
  • 175
  • That third line is hideous! :) Why not doing something like (reg instanceof RegExp)? It is shorter and clearer... – Jason Bunting Jun 03 '09 at 21:45
  • Jason, that way won't work across different frames... (different windows) – James Jun 03 '09 at 21:48
  • I had some time and made a fully-featured "prettyPrint" function for JavaScript: http://james.padolsey.com/javascript/prettyprint-for-javascript/ – James Jun 05 '09 at 19:10
3

I just saw this today, maybe this is what you're looking for?

Dan Lew
  • 85,990
  • 32
  • 182
  • 176
  • Hahaha, apparently I'm not the only person who is a regular on both reddit and stack overflow. ;) – Dan Lew Jun 07 '09 at 04:30
  • 1
    There is a certain irony that the selected answer here was written by the guy who wrote the blog entry you are referring to. :) – cgp Jun 15 '09 at 14:06
2

I havn't run across such a debugger although it doesn't seem like this particular style would be too hard to write on your own. Just a basic recursive function passing in the current object and a table cell to start writing too, then just build as you go.

As for the circular reference comment above, this can be circumvented easily by keeping an array of objects that you have already processed. Before processing an object, check if it is already in the list. if so, denote that in the value field of your output as something like "circular reference to"...however you want to denote the object up the hierarchy.

prettyprint(object, processedObjects)
{
    if (processedObjects.contains(object))
        return 'circular refernece';

    processedObjects.push(object);

    create newTable;

    for (var in object)
    {
        row = newTable.addRow();
        row.cell1.value = var;
        if (typeof object[var] is object)
            row.cell2.value = prettyprint(object[var], processedObjects);
        else if (typeof object[var] is function)
            row.cell2.value = '[function]';
        else
            row.cell2.value = object[var].toString();
    }

    return newTable;
}
Mike Clark
  • 11,769
  • 6
  • 39
  • 43
2

I think what you are looking for is this, http://www.netgrow.com.au/files/javascript_dump.cfm it's the javascript equivalent of coldfusion's dump tag

jalpino
  • 150
  • 5