Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What state of the object the logging methods should display ? #19

Open
fflorent opened this issue Oct 19, 2013 · 15 comments
Open

What state of the object the logging methods should display ? #19

fflorent opened this issue Oct 19, 2013 · 15 comments

Comments

@fflorent
Copy link

To illustrate the question, just enter this expression in the different Dev Tools Consoles:

var o = {a: 1, b: { c: 2 } };
console.log(o);
o.a = 3;

Some Dev Tools offer a preview of the object being logged. That is the case of Firebug and Chrome Dev Tools.
In Firebug:

>>> var o = {a: 1, b: { c: 2 } }; console.log(o); o.a = 3;
Object { a=1, b={...} }

And in Chrome :

> var o = {a: 1, b: { c: 2 } }; console.log(o); o.a = 3;
Object {a: 1, b: Object}

However:

  • When expanding the logged object in Chrome, the object state is displayed like at the first expansion ;
  • When clicking on the object in Firebug, the last state of the object is displayed.

However, in the Firefox Dev Tools or in Opera Dragonfly, the user has to click on the object to display its properties, and only the last state is displayed.

So, to sum up, the question of the title: What state of the object the logging methods should display on the Console logs ?

Some related problematics:

  • performance (how to avoid performance issues with the logging methods)
  • consistency (what state of the object the user wants to see?)
  • others?

Florent

@bkardell
Copy link
Member

This is a really interesting issue - it might even be two issues if we want to get into the true sense of it because lots of stuff is going into making things parallelizable now, so maybe we should actually include some SHOULD advice about lazy writing off the thread or something. The state of the object seems kind of important to specify though. Thanks!

@SebastianZ
Copy link
Contributor

Also instead of just deciding ourselves whether the current state of the object or the one at the time the object was logged should be displayed, there could be some survey asking the users about what they'd expect when logging an object.

Personally I believe showing the user the old state has more value for him, because then he has the possibility to trace changes to the object. The downsides are related to performance and memory usage, of course, because everytime an object is logged, a copy needs to be created.

Sebastian

@paulirish
Copy link
Member

Great issue. Before Chrome changed its behavior we had a lot of people very very confused. Now afterwards we have some people confused.
Regardless, it'd be good to document.

@0b10011
Copy link

0b10011 commented Dec 19, 2013

Personally, I prefer the state of the object when console.log() is called. To workaround Firefox's behavior, I usually abuse JSON.stringify(), but it's by no means ideal. But, in any case, it would be nice if it was consistent across browsers.

@jonah-williams
Copy link

I would expect to see the state of the object at the time it was logged. A watch is a useful debugging tool but it should be exposed as such, not hidden in a "log" call. I' even prefer the browser refusing to expand an object if it were too expensive to preserve a copy rather than present a potentially misleading state.

@reconbot
Copy link

I'm in the, "show what is looks like when it was called" camp. I wouldn't expect any other kind of log to change on me, I don't expect the console log to either. However, seeing the current state of an object is a really useful feature, just a different one. I'd love to have that ability. Maybe console.spy() could add weak reference to a list that you could browse at a later point in time?

@davidagee
Copy link

+1 for "show it in the state it's in when log is called". The alternative is a bit of a landmine - it sounds like it displays the state of the object when you click to expand it, so it's not like it's actually acting as console.spy(), it's just a snapshot to an arbitrary, not very useful point in time.

@mgol
Copy link

mgol commented Dec 20, 2013

I agree with @davidagee. I realize having the whole logged object reglect the state when it's called can be impossible but at least keeping the preview accurate is very useful.

@webdesserts
Copy link

Maybe there should be two seprate console functions? One for state "snapshots" (log preferably) and another for current state. console.spy() sounds like a good idea. Maybe call it console.watch()? It would be really cool if you could see the values update in realtime inside the console.

@fflorent
Copy link
Author

I haven't mentioned that before, but to avoid big memory and performance issues, I think we should avoid to copy deeply the logged object, and rather:

  • offer a shallow copy
  • or/and let the user to copy the object as they want.

Florent

@DougReeder
Copy link

As a developer, I expect the log to show the state of the object at the time it was logged. The only question for me is, how deep a copy of the object graph should be made? Two levels should be enough for most purposes, but if an implementation wants to save more, it could. Shallow copies can also also take up a lot of space. I'm also okay with an implementation limiting the size of stored objects; if the top-level object logged has 65,000 properties, I don't expect (or want) the log to show them all.

UI to create a watch on a logged object would be nice, but I'd leave that up to implementors.

@fflorent
Copy link
Author

In fact, I think a shallow (1-level deep) copy is enough: we copy the primitive-valued properties and only the reference of properties whose values are complex objects. At least, by default.

Florent

@mgol
Copy link

mgol commented Dec 20, 2013

@fflorent You mean for the whole object representation? That would be terribly misleading. Take the code:

var o = { a: [1], b: [2] };
console.log(o);
delete o.a;
o.b[0] = 3;
o.c = [4];

I'd expect to get either the whole deep copy of the initial value or the final value (i.e. { b: [3], c: [4] }) but definitely not { a: [1], b: [3] }...

We should differentiate between what' shown in a shortcut and what's the inspected object when looking beyond the shortcut. But within one of these realms, we shouldn't have a shallow copy.

@fflorent
Copy link
Author

I'd expect to get either the whole deep copy of the initial value or the final value (i.e. { b: [3], c: [4] }) but definitely not { a: [1], b: [3] }...

Indeed... I admit that it may not be the ideal in that case.

I'd expect to get the whole deep copy of the initial value

This would have terrible impacts for performance and memory. Just consider this: console.log(window);... Ouch!

That's why I'd rather leave the responsibility to copy the logged object to the user. But still, the default behavior should be fast and user-friendly.

Florent

@mgol
Copy link

mgol commented Dec 20, 2013

@fflorent

I'd expect to get the whole deep copy of the initial value

This would have terrible impacts for performance and memory. Just consider this: console.log(window);... Ouch!

I know. That's why I like Chrome's approach that separates:

  1. the object that you can play with - not deep copied, just a reference
  2. its string shortcut - a shallow copy
    A shallow copy works here only because the string shortcut doesn't let you expand values, it just prints the first level and that's it, you can only inspect the object from (1).

I think that strategy played pretty well for Chrome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests