Console.Log() Shows the Changed Value of a Variable Before the Value Actually Changes

console.log() shows the changed value of a variable before the value actually changes

Pointy's answer has good information, but it's not the correct answer for this question.

The behavior described by the OP is part of a bug that was first reported in March 2010, patched for Webkit in August 2012, but as of this writing is not yet integrated into Google Chrome. The behavior hinges upon whether or not the console debug window is open or closed at the time the object literal is passed to console.log().

Excerpts from the original bug report (https://bugs.webkit.org/show_bug.cgi?id=35801):

Description From mitch kramer 2010-03-05 11:37:45 PST

1) create an object literal with one or more properties

2) console.log that object but leave it closed (don't expand it in the console)

3) change one of the properties to a new value

now open that console.log and you'll see it has the new value for some reason, even though it's value was different at the time it was generated.

I should point out that if you open it, it will retain the correct value if that wasn't clear.

Response from a Chromium developer:

Comment #2 From Pavel Feldman 2010-03-09 06:33:36 PST

I don't think we are ever going to fix this one. We can't clone object upon dumping it into the console and we also can't listen to the object properties' changes in order to make it always actual.

We should make sure existing behavior is expected though.

Much complaining ensued and eventually it led to a bug fix.

Changelog notes from the patch implemented in August 2012 (http://trac.webkit.org/changeset/125174):

As of today, dumping an object (array) into console will result in objects' properties being
read upon console object expansion (i.e. lazily). This means that dumping the same object while
mutating it will be hard to debug using the console.

This change starts generating abbreviated previews for objects / arrays at the moment of their
logging and passes this information along into the front-end. This only happens when the front-end
is already opened, it only works for console.log(), not live console interaction.

Why does console log, log out a variable thats already been assigned as the new assignment

This is an implementation quirk. Chrome (V8) and Firefox (SpiderMonkey) will resolve to the object at the time you expand the object in the console. Behind the scenes, the value might have changed. WebKit (Safari) will log it as it is. If you want to capture the object as it is at a certain point in time, use console.log(JSON.parse(JSON.stringify(obj)));

[1] https://developer.mozilla.org/en-US/docs/Web/API/Console/log#Logging_objects

P.S Javascript is littered with these kinds of quirks. Not to discourage you, but what should be is quite frequently not what it is. This example also draws close parallels to asynchronous programming in javascript which can be jarring to those coming from procedural backgrounds. To oversimplify, your value will change behind the scenes before you reach the next line and thus it's a good idea to understand the event loop, callbacks and subsequently promises and async/await.

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

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)));

How can this strange behaviour of console.log() in vue.js be explained?

Console logging an object/array is 'live'. The console just stores a reference to the object. The values of the properties aren't captured until you expand the object in the console, by which time your object will have changed.

JSON.stringify can be useful to capture a string version of the object. As it's a string it can be logged without any risk of it changing. For that to work it does require that the object can be converted to JSON, which is not always possible.

The map example is a bit different. You aren't mutating the same object that was logged. Just assigning a new value to HighData won't change the value seen in the console as that is still pointing at the original object.

Why does this loop repeatedly log the last pair in the array instead of all the pairs?

In javascript, when you do let a:any = {}; and then let b = a; you are assigning to b the references of a (not the value). So if you update b, you are actually updating a because both variable are the same.

If you want b to be a copy of a you should do something like : let b = {...a}.

Why does wrapping an array in an object changes the data in JavaScript?

The comment of VLAZ got it. I accidentially changed the data in a second function that is called later, so it seems the logging is just to slow.



Related Topics



Leave a reply



Submit