2

javascript console.log gives confusing result. I executed the code.

    var obj = {a: {b: {c: {}}}};
    console.log(obj);
    obj.a.b.c.name = "rafael";

then I look at the console window and expand the object. It was

Object{a: {b: {c: {name: "sohan"}}}}

But I expected it to be

Object{a: {b: {c: {}}}}

Why this confusing behavior?

sohan nohemy
  • 615
  • 5
  • 13
  • 1
    this is covered here: http://stackoverflow.com/questions/7389069/console-log-object-at-current-state – TMG Nov 15 '15 at 11:11

3 Answers3

1

Console behaviour is quirky and will vary depending on the browser and console. On Google Chrome, objects that are logged to the browser are lazy-evaluated upon first expansion.

Meaning that, if you log an empty object x into the console, and expand it (the object tree) to peek at it, it will evaluate the value of x and display the value in the console as {}. However, if you subsequently add properties before you actually expand it, it will display the object as it currently exists in memory. So if you do x.test = 1, it will display as { test: 1 }.

sahbeewah
  • 2,690
  • 1
  • 12
  • 18
  • *"objects that are logged to the browser are lazy-evaluated upon first expansion"* **Sometimes**. It varies depending, amongst other things, on whether you had the console open when the logging was done. – T.J. Crowder Nov 15 '15 at 11:09
1

Summary: resolution of mutable objects seems to be deferred until the moment you inspect them in the console. This makes sense, because if you were to have captured the state of a mutable object on logging, it'd take a lot of memory to do deep copies of objects every time you log them.

More details and an example to show this behavior: Behavior may differ by browser, but in Chrome the behavior I observe, is that a reference to the JS object is logged at your console.log(obj). The values of that reference are deferred until you try to expand the object in your console. Try this:

var obj = {a: {b: {c: {}}}};
console.log(obj);

Then expand out the reference (obj -> a -> b -> c), verifying that there isn't a property "name" set yet.

Then assign the property:

obj.a.b.c.name = "rafael";

Compare this to the behavior you described:

var obj = {a: {b: {c: {}}}};
console.log(obj);
obj.a.b.c.name = "rafael";

Then expanding the object reference to see that the "name" property of object C has already been set, since we merely logged the reference to the object.

0

The only thing that is confusing is the name being changed. That's just voodoo (or maybe an edit on your part). But you are logging to the console before applying the value to the new property. Try this instead.

var obj = {a: {b: {c: {}}}};
obj.a.b.c.name = "rafael";
console.log(obj); //console after applying the value

You should get Object{a: {b: {c: {name: "rafael"}}}}

Donnie D'Amato
  • 3,832
  • 1
  • 15
  • 40