Weird Behavior With Objects & Console.Log

Weird behavior with objects & console.log

Examining objects via console.log happens in an asynchronous manner. The console receives a reference to the object synchronously, but does not display the properties of the object until it is expanded (in some cases, depending on the browser and whether you have dev tools open when the log happens). If the object has been modified before examining it in the console, the data shown will have the updated values.

For example, Chrome will show a little i in a box which, when hovered, says:

Object value at left was snapshotted when logged, value below was evaluated just now.

to let you know what you're looking at.

One trick for logging in these cases is to log the individual values:

console.log(obj.foo, obj.bar, obj.baz);

Or JSON encode the object reference:

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

Javascript console.log weird behavior on browser console

console.log has different inner working between chrome, firefox, nodejs, and other javascript engine.

In your screenshot, the browser does 2 things:

  1. prints the short preview of the action object
  2. prints the expandable reference of the action object

The short preview is a readable version snapshot of the object at the time console.log is called

The expendable reference only prints an expand icon at the time console.log is called.
When expanded, chrome will fetch the CURRENT value the object referenced by that expendable reference and print it. It doesn't print the value when console.log is called

Since the value when the console.log is called ({value1: 17, value2: 0}), and the current value ({value1: 17, value2: 17}) is different, it prints different thing.

Weird behaviour of console.log() in an object

You create a foo object, and you assign it two properties:

  • You set a be a function with the text function(){console.log(this)}
  • You set bto be the return value from console.log(this). console.log(this) gets executed immediately, and logs out the object. The object hasn't been given its properties yet, so it logs out {}. The return value of console.log() is undefined, so b gets set to undefined.

You've now initialized your object, with a = some function and b = undefined. Later, when you call a, it logs out the foo object, with a = some function, and b = undefined.

Weird behaviour in chrome object console.log

The debugger can't know if an object has been altered, this is why the posts attribute's rendering (in your example) has not been updated. Even if the debugger would be able to know when a attribute has been changed updating it every time (and all "loggings") would be too expensive.

So the debugger will check the attribute only when accessing it explicitly.

Chrome in this case will do this even only once:

p = []; window.x = {x: p}; 
Object {x: Array[0]}
x: Array[0]
__proto__: Object
x.x.push(1);
1
x.x.push(2);
2

Klicking x, the Array updates

p = []; window.x = {x: p}; 
Object {x: Array[2]}
x: Array[2]
0: 1
1: 2
length: 2
__proto__: Array[0]
__proto__: Object

Adding one item more to the array and toggleing x again, the size and entries remain

x.x.push(3)
3

x: Array[2]
0: 1
1: 2
length: 2
__proto__: Array[0]

In my opinion it's not necessary for the logger to update the object value since the variable watch has this function already. There you can always update the current value of a variable.

This works in Firebug and Chrome. Here's an example for Chrome:

Chrome: how to update variables in debugger watch

Weird Behavior from Console.log() in promises

doSomething("2nd Call");
console.log('leaving 2nd promise');

Do something is asynchronous and will take ~1000 m/s to finish its execution. So, when doSomething("2nd Call"); is initially called, your code jumps into your method, returns the promise, and begins the setTimeout. Then, "leaving 2nd promise" is logged. Later on down the track, the setTimeout that we initiated before by calling doSomething("2nd Call") will finish, and so it will log "2nd Call" to the console. To wait for your inital call to doSomething("2nd Call") to complete, you need to use .then() (or await) on the promise it returns, such you can execute your code when the promise resolves:

function doSomething(msg) {

return new Promise(

(myresolve, myreject) => {

setTimeout(

() => {

console.log(msg);

console.log('In the promise')

myresolve();

},

1000);

});

}

doSomething("1st Call")

.then(() => doSomething("2nd Call"))

.then(() => console.log('leaving 2nd promise'))

.then(() => doSomething("3rd Call"))

.then(() => console.log('leaving 3rd promise'));

Weird console.log behavior in Chrome dev tools?

This happens when the element is edited after it was logged. Chrome just shows you a pointer to that element. If 2 and 3 are removed after console.log() they are shown in the preview, but not when you inspect the element.

weird behavior of javascript objects when assigning a value to it

JavaScript Objects are Mutable. They are addressed by reference, not by value.

If jsonObj_1 is an object, the following statement will not create a copy of jsonObj_1:

var jsonObj_2 = jsonObj_1 ;  // This will not create a copy of jsonObj_1.


Related Topics



Leave a reply



Submit