105

How can I inspect an Object in an alert box? Normally alerting an Object just throws the nodename:

alert(document);

But I want to get the properties and methods of the object in the alert box. How can I achieve this functionality, if possible? Or are there any other suggestions?

Particularly, I am seeking a solution for a production environment where console.log and Firebug are not available.

Peter David Carter
  • 2,548
  • 8
  • 25
  • 44
Valentina
  • 1,053
  • 2
  • 8
  • 5
  • 9
    do `console.log` on firefox or chrome – KJYe.Name Mar 18 '11 at 20:24
  • 1
    I'm confused. In a production environment, you've got actual users, right? So why would you want to throw an alert with object properties? Maybe a better solution is to serialize the object and log it in a file or send an email? – Nathan Long Mar 19 '11 at 00:17
  • Maybe s/he needs the alert as a tool, but the actual functionality to do something else. There could be all sorts of reasons why s/he might want to do this, such as showing statistics, or an error occurrence, or doing both by simply passing an object to whatever s/he is using to inspect the object. – Christian Mar 21 '11 at 00:06
  • Related on Node.js: http://stackoverflow.com/questions/24902061/is-there-an-repr-equivalent-for-javascript – Ciro Santilli OurBigBook.com Nov 02 '14 at 10:44
  • Sometimes `JSON.stringify` is helpful. – BrainSlugs83 Jun 25 '15 at 20:07

8 Answers8

198

How about alert(JSON.stringify(object)) with a modern browser?

In case of TypeError: Converting circular structure to JSON, here are more options: How to serialize DOM node to JSON even if there are circular references?

The documentation: JSON.stringify() provides info on formatting or prettifying the output.

Community
  • 1
  • 1
Torsten Becker
  • 4,330
  • 2
  • 21
  • 22
  • +1 Good suggestion. I'd add he could use jsonview (http://jsonviewer.stack.hu/) to see it nicely. – Christian Mar 18 '11 at 21:27
  • 2
    If you wanted to have it nicely formatted too you could call: `alert(JSON.stringify(object, null, 4)`, where `4` is the number of spaces used for indentation. – Jan Molak Aug 05 '14 at 13:02
  • This gives me 'undefined' as output. I am trying to debug karma tests. – Alex C Mar 27 '15 at 19:41
  • 1
    There are caveats to this approach. OP says that she wants to inspect object's methods. `stringify ` won't show methods: `JSON.stringify({f: ()=>{}}) => "{}"`. Also, if the object implements `toJSON` method you get what that method returns, which is useless if you want to inspect the object: `JSON.stringify({toJSON: () => 'nothin'}) => '"nothin"'`. – Morozov Sep 26 '18 at 14:33
58

The for-in loops for each property in an object or array. You can use this property to get to the value as well as change it.

Note: Private properties are not available for inspection, unless you use a "spy"; basically, you override the object and write some code which does a for-in loop inside the object's context.

For in looks like:

for (var property in object) loop();

Some sample code:

function xinspect(o,i){
    if(typeof i=='undefined')i='';
    if(i.length>50)return '[MAX ITERATIONS]';
    var r=[];
    for(var p in o){
        var t=typeof o[p];
        r.push(i+'"'+p+'" ('+t+') => '+(t=='object' ? 'object:'+xinspect(o[p],i+'  ') : o[p]+''));
    }
    return r.join(i+'\n');
}

// example of use:
alert(xinspect(document));

Edit: Some time ago, I wrote my own inspector, if you're interested, I'm happy to share.

Edit 2: Well, I wrote one up anyway.

Christian
  • 27,509
  • 17
  • 111
  • 155
  • Should be somehow protected from recursion. Hashes(*dictionaries*) with some internal html-renderer ids? Could be useful for noobs to push this check into the code. – Nakilon Apr 03 '12 at 06:58
  • @Nakilon I've always taken issue with infinite recursion, especially in PHP. There are two ways to fix this: using a depth parameter, or modifying the hash and add your own property which you use to check for recursion. The depth one is probably safer. – Christian Apr 03 '12 at 07:08
  • I like this version of line 7 better. It looks a little more like ruby and does some nice whitespace r.push(i+'"'+p+'" => '+(t=='object' ? '{\n'+xinspect(o[p],i+' ')+('\n' + i + '},') : o[p]+'')); – BC. Jun 12 '12 at 21:20
  • 2
    That piece of code totally wrecked Safari Mobile on iPhone. I'd go for the JSON.stringify solution below for a safer alternative. – Daniel Aug 29 '12 at 09:35
  • 1
    This thing crashed safari,chrome inspecting an object, would not recommend. – Keno Dec 12 '16 at 22:19
  • 'Yucky' in Firefox too. **Instead, use [`alert(JSON.stringify(object))`](https://stackoverflow.com/a/5357946/8112776).** – ashleedawg May 20 '19 at 14:07
40

Use console.dir(object) and the Firebug plugin

zangw
  • 43,869
  • 19
  • 177
  • 214
Ranjeet
  • 595
  • 5
  • 8
  • 4
    This gave me the most complete and helpful information for what I was after. Thanks. – Shon Mar 04 '14 at 00:42
  • 2
    I wasn't aware of the `console.dir` feature. I couldn't work out why I could no longer view the full object in Firebug. This has now sorted it for me. Thanks! – Andrew Newby Jul 01 '16 at 12:04
  • I need to know if there is other advantages of this over `console.log` besides the displaying convenience, please – user10089632 Aug 23 '17 at 16:45
19

There are few methods :

 1. typeof tells you which one of the 6 javascript types is the object. 
 2. instanceof tells you if the object is an instance of another object.
 3. List properties with for(var k in obj)
 4. Object.getOwnPropertyNames( anObjectToInspect ) 
 5. Object.getPrototypeOf( anObject )
 6. anObject.hasOwnProperty(aProperty) 

In a console context, sometimes the .constructor or .prototype maybe useful:

console.log(anObject.constructor ); 
console.log(anObject.prototype ) ; 
brotherol
  • 361
  • 2
  • 6
17

Use your console:

console.log(object);

Or if you are inspecting html dom elements use console.dir(object). Example:

let element = document.getElementById('alertBoxContainer');
console.dir(element);

Or if you have an array of js objects you could use:

console.table(objectArr);

If you are outputting a lot of console.log(objects) you can also write

console.log({ objectName1 });
console.log({ objectName2 });

This will help you label the objects written to console.

Richard Torcato
  • 2,504
  • 25
  • 26
  • Those displayed values change dynamically, in real time which can be misleading for debugging purposes – user10089632 Aug 23 '17 at 14:55
  • in chrome use your console preferences and click preserve log. Now even if your script redirects you to another page your console is not cleared. – Richard Torcato Aug 23 '17 at 16:07
  • It seems that this issue is Firefox related because in Chrome unless you re console.log() the displayed values are still. You might suggest to move to Chrome but sometimes you're testing browser features availability. Anyway thanks for the tip that may be useful. – user10089632 Aug 23 '17 at 16:27
  • I cannot use `console` because I'm using styling https://stackoverflow.com/q/7505623/1480391 and it's not compatible – Yves M. May 15 '18 at 08:33
9
var str = "";
for(var k in obj)
    if (obj.hasOwnProperty(k)) //omit this test if you want to see built-in properties
        str += k + " = " + obj[k] + "\n";
alert(str);
Joseph Bui
  • 1,701
  • 15
  • 22
moe
  • 28,814
  • 4
  • 19
  • 16
6

This is blatant rip-off of Christian's excellent answer. I've just made it a bit more readable:

/**
 * objectInspector digs through a Javascript object
 * to display all its properties
 *
 * @param object - a Javascript object to inspect
 * @param result - a string of properties with datatypes
 *
 * @return result - the concatenated description of all object properties
 */
function objectInspector(object, result) {
    if (typeof object != "object")
        return "Invalid object";
    if (typeof result == "undefined")
        result = '';

    if (result.length > 50)
        return "[RECURSION TOO DEEP. ABORTING.]";

    var rows = [];
    for (var property in object) {
        var datatype = typeof object[property];

        var tempDescription = result+'"'+property+'"';
        tempDescription += ' ('+datatype+') => ';
        if (datatype == "object")
            tempDescription += 'object: '+objectInspector(object[property],result+'  ');
        else
            tempDescription += object[property];

        rows.push(tempDescription);
    }//Close for

    return rows.join(result+"\n");
}//End objectInspector
vaFyreHeart
  • 275
  • 1
  • 3
  • 13
4

Here is my object inspector that is more readable. Because the code takes to long to write down here you can download it at http://etto-aa-js.googlecode.com/svn/trunk/inspector.js

Use like this :

document.write(inspect(object));
Victor2748
  • 4,149
  • 13
  • 52
  • 89
  • 2
    That's usually the case (and it's definitely the official guidance -- don't post links), OTOH, for something that's versioned like this, it can be kind of nice, since you know that you're always going to be looking at the latest code, and not some stale thing that was posted years ago and might not work anymore... -- Also, that huge block of code would look pretty awful pasted into a wall of text SO answer... -- **Off topic:** it would be nice if there was a way on SO to have "spoiler"-like tags for code and to be able to link to an external source and have it auto update (when possible), – BrainSlugs83 Jun 25 '15 at 20:14