What's the difference between console.dir and console.log?

In Firefox, these function behave quite differently: log only prints out a toString representation, whereas dir prints out a navigable tree.

In Chrome, log already prints out a tree -- most of the time. However, Chrome's log still stringifies certain classes of objects, even if they have properties. Perhaps the clearest example of a difference is a regular expression:

> console.log(/foo/);
/foo/

> console.dir(/foo/);
* /foo/
    global: false
    ignoreCase: false
    lastIndex: 0
    ...

You can also see a clear difference with arrays (e.g., console.dir([1,2,3])) which are logged differently from normal objects:

> console.log([1,2,3])
[1, 2, 3]

> console.dir([1,2,3])
* Array[3]
    0: 1
    1: 2
    2: 3
    length: 3
    * __proto__: Array[0]
        concat: function concat() { [native code] }
        constructor: function Array() { [native code] }
        entries: function entries() { [native code] }
        ...

DOM objects also exhibit differing behavior, as noted on another answer.


Another useful difference in Chrome exists when sending DOM elements to the console.

Notice:

  • console.log prints the element in an HTML-like tree
  • console.dir prints the element in a JSON-like tree

Specifically, console.log gives special treatment to DOM elements, whereas console.dir does not. This is often useful when trying to see the full representation of the DOM JS object.

There's more information in the Chrome Console API reference about this and other functions.


I think Firebug does it differently than Chrome's dev tools. It looks like Firebug gives you a stringified version of the object while console.dir gives you an expandable object. Both give you the expandable object in Chrome, and I think that's where the confusion might come from. Or it's just a bug in Chrome.

In Chrome, both do the same thing. Expanding on your test, I have noticed that Chrome gets the current value of the object when you expand it.

> o = { foo: 1 }
> console.log(o)
Expand now, o.foo = 1
> o.foo = 2
o.foo is still displayed as 1 from previous lines

> o = { foo: 1 }
> console.log(o)
> o.foo = 2
Expand now, o.foo = 2

You can use the following to get a stringified version of an object if that's what you want to see. This will show you what the object is at the time this line is called, not when you expand it.

console.log(JSON.stringify(o));