How can I make console.log show the current state of an object?
Asked Answered
P

12

166

In Safari with no add-ons (and actually most other browsers), console.log will show the object at the last state of execution, not at the state when console.log was called.

I have to clone the object just to output it via console.log to get the state of the object at that line.

Example:

var test = {a: true}
console.log(test); // {a: false}
test.a = false; 
console.log(test); // {a: false}
Parfleche answered 12/9, 2011 at 13:57 Comment(3)
jsfiddle example of the problem and various solutions given below: jsfiddle.net/luken/M6295Medusa
It is extremely counterintuitive for the log function to output a live reference to the object. That is called a watch, which is much different than a log entry. It doesn't make any more sense to do this when logging an object than it would when logging a variable storing a primitive value.Catachresis
How have I never some across this before? I find this frighteningHardden
C
183

I think you're looking for console.dir().

console.log() doesn't do what you want because it prints a reference to the object, and by the time you pop it open, it's changed. console.dir prints a directory of the properties in the object at the time you call it.

The JSON idea below is a good one; you could even go on to parse the JSON string and get a browsable object like what .dir() would give you:

console.log(JSON.parse(JSON.stringify(obj)));

Claw answered 12/9, 2011 at 14:6 Comment(11)
For me in Chrome13 no difference between console.log and console.dirPluvious
Hm, that's surprising- it works in Firebug. I had thought it was the same in Webkit.Claw
What I'm seeing in Chrome is that if you open the console after the log statement has run, then it'll do the lazy evaluation when you expand it. But if the console is already open (e.g. you open the console and then hit refresh on the page), it'll do eager evaluation -- i.e. print the value at the time the log statement was run.Hydrolyze
Also, dir is to JSON as shallow-copy is to deep-copy. console.dir() will only evaluate the top-level object's properties (other more deeply nested objects wouldn't be evaluated), whereas JSON will go recursively.Hydrolyze
Likewise for me console.dir does not work in Chrome (v33). Here's a comparison of the solutions that people have offered: jsfiddle.net/luken/M6295Medusa
I didn't experience the effect that Polemarch did. I had the console open all the time, and console.dir still didn't behave differently from console.log.Aerostatic
console.dir() gave me an expanded listing in firefox, which is not the case with console.log(). Can I have them both collapsed?Unrelenting
Usually console.dir() does the trick, but today is showing only a little tooltip that when hovered, says "Object state below is captured upon first expansion". What?Amateur
console.dir and console.log do not seem to behave differently. Relevant: code.google.com/p/chromium/issues/detail?id=508719 (Link also clears @jerome's question)Lecky
At the time of writing, .log and .dir behaved differently.Claw
In conclusion: console.dir(); don't works (at least in Chrome!) and print the reference too. So you should use the JSON idea: console.log(JSON.parse(JSON.stringify(obj))); (as mentioned second in evans answer)Alleged
A
74

What I usually do if I want to see it's state at the time it was logged is I just convert it to a JSON string.

console.log(JSON.stringify(a));
Arduous answered 12/9, 2011 at 14:10 Comment(5)
Great, that was a nice hint for me : I just had to parse it again to have my object right in the console. function odump(o){ console.log($.parseJSON(JSON.stringify(o))); }Perceivable
thanks this works for me! console.dir didn't print itChibouk
what if your object happens to contain a circular structure?Hardtack
@AlexMcMillan You could use one of several libraries that allow for JSON stringification of objects with circular references.Arduous
Geez. This should be a simple, obvious thing to be able to do. Instead we have to stringify, parse, log, and use a special circular reference library!?! I think the browsers need to do a better job of supporting simple debugging needs.Coachwhip
F
32

Vanilla JS:

@evan's answer seems best here. Just (ab)use JSON.parse/stringify to effectively make a copy of the object.

console.log(JSON.parse(JSON.stringify(test)));

JQuery specific solution:

You can create a snapshot of an object at a certain point in time with jQuery.extend

console.log($.extend({}, test));

What is actually happening here is jQuery is creating a new object with the test object's content, and logging that (so it will not change).

AngularJS (1) specific solution:

Angular provides a copy function that can be used to the same effect: angular.copy

console.log(angular.copy(test));

Vanilla JS wrapper function:

Here is an function which wraps console.log but will make a copy of any objects before logging them out.

I wrote this in response to a few similar but less robust functions in the answers. It supports multiple arguments, and will not try to copy things if they are not regular objects.

function consoleLogWithObjectCopy () {
  var args = [].slice.call(arguments);
  var argsWithObjectCopies = args.map(copyIfRegularObject)
  return console.log.apply(console, argsWithObjectCopies)
}

function copyIfRegularObject (o) {
  const isRegularObject = typeof o === 'object' && !(o instanceof RegExp)
  return isRegularObject ? copyObject(o) : o
}

function copyObject (o) {
  return JSON.parse(JSON.stringify(o))
}

example usage: consoleLogWithObjectCopy('obj', {foo: 'bar'}, 1, /abc/, {a: 1})

Flyblow answered 12/3, 2013 at 15:4 Comment(0)
E
8

That > Object in the console, isn't only showing the current state. It actually is deferring reading the object and it's properties until you expand it.

For example,

var test = {a: true}
console.log(test);
setTimeout(function () {
    test.a = false; 
    console.log(test);
}, 4000);

Then expand the first call, it will be correct, if you do it before the second console.log returns

Ermelindaermengarde answered 12/9, 2011 at 14:8 Comment(0)
P
2

using Xeon06's hint, you may parse his JSON in an object, and here is the log function I now use to dump my objects :

function odump(o){
   console.log($.parseJSON(JSON.stringify(o)));
}
Perceivable answered 29/3, 2013 at 19:41 Comment(0)
J
2

There is an option to use a debugger library.

https://debugjs.net/

Just include the script into your web page and put log statements.

<script src="debug.js"></script>

Logging

var test = {a: true}
log(test); // {a: true}
test.a = false; 
log(test); // {a: false}
Juncture answered 8/2, 2017 at 15:25 Comment(0)
F
1

I defined an utility:

function MyLog(text) {
    console.log(JSON.stringify(text));
}

and when I want to log on console I simply do:

MyLog("hello console!");

It works very well!

Flap answered 2/4, 2014 at 22:4 Comment(0)
W
1

You might want to log the object in a human readable way:

console.log(JSON.stringify(myObject, null, 2));

This indents the object with 2 spaces at each level.

How can I pretty-print JSON using JavaScript?

Widespread answered 9/12, 2016 at 14:33 Comment(0)
O
1

There's a new option as of late 2022: Deep copy the object with the new DOM structuredClone method:

console.log(structuredClone(obj))

which uses the same cloning algorithm that's used to transfer messages between web workers.

This should be faster and work with more types of objects than the JSON.parse(JSON.stringify(obj)) technique.

See https://developer.mozilla.org/en-US/docs/Web/API/structuredClone for details.

Owl answered 19/12, 2022 at 21:12 Comment(0)
R
-1

I may be shot for suggesting this, but this can be taken one step further. We can directly extend the console object itself to make it more clear.

console.logObject = function(o) {
  (JSON.stringify(o));
}

I don't know if this will cause some type of library collision/nuclear meltdown/rip in the spacetime continuum. But it works beautifully in my qUnit tests. :)

Radioluminescence answered 21/4, 2014 at 21:31 Comment(2)
This doesn't log anything. It just swallows the result of stringify-ing something. Funny that its gotten upvotesFlyblow
Please add some explanation to your answer such that others can learn from itKhano
R
-2

Simply refresh the page after you open the console or open the console before you submit the request to the targeted page....

Retrocede answered 15/1, 2017 at 10:42 Comment(1)
Please add some explanation to your answer such that others can learn from itKhano
Y
-5

Just print whole object on console.

console.log(object);

see console screen shot for ref

Yestreen answered 6/1, 2016 at 6:12 Comment(2)
This displays the state of the object at the current time, not at the time of logging.Widespread
Please add some explanation to your answer such that others can learn from it. If console.log() prints unexpected output, how does your answer help to resolve this?Khano

© 2022 - 2024 — McMap. All rights reserved.