19

Possible Duplicate:
Is Chrome's JavaScript console lazy about evaluating arrays?

Consider this javascript:

var foo = {bar : 1111};
console.log(foo);
console.log(foo.bar);

foo.bar = 2222;
console.log(foo);
console.log(foo.bar);

In Firefox's firebug, this shows what I would have expected:

Object { bar=1111}
1111

Object { bar=2222}
2222

However, in Safari and Chrome's console it shows:

Object { bar=2222}
1111

Object { bar=2222}
2222

In other words, the object is showing the wrong attributes in the console when print-dumped, but the correct value if a specific attribute is printed.

Is this a quirk of the browsers? Or a fundamental aspect of object oriented javascript that I am missing?

7
  • 2
    If I had to guess, I'd say the debugger is storing a reference to the object in memory for the first one, and the value itself for the second one. Since your code updates the reference, the value in the debugger being watched also gets updated. Total wild guess though. Commented Nov 23, 2011 at 21:15
  • 2
    Best guess would be that Safari and Chrome are optimizing the JavaScript and combining the assignment to foo.bar with the original object definition, then inlining the expected value of foo.bar on the two console.log statements. Commented Nov 23, 2011 at 21:15
  • 2
    Thanks Mike and John. It does appear that this is the case doesn't it. I have to say, in my eyes this means Safari and Chrome are telling me lies about my code while I'm trying to debug! If I want to quickly see what an object contains at two points in the code during execution, then Safari and Chrome are not giving me a true representation. Perhaps my debugging routine is not sophisticated enough and I shouldn't be relying on manual console.log lines in the code? Commented Nov 23, 2011 at 21:23
  • This has come up before, I'm going to try to find it. Commented Nov 23, 2011 at 21:24
  • @OskarSmith I suspect that the example you gave is also too trivial to really test the behavior. I suspect that the optimization is being done because their is no "work" being done with the object between the creation and the re-assignment of foo.bar. If there was some work, such as a method call, I would suspect that you would get the behavior you are looking for. Commented Nov 23, 2011 at 21:26

1 Answer 1

29

In Chrome (WebKit, so Safari also), console.log calls with object arguments log an object reference. Once the object tab is clicked and opened, the internals remain constant (presumably a cache of sorts) and are no longer related to the object initially referred to (so if at a later stage the object changes, this will not be reflected). However until that point the object remains "uncached". So when you log an object multiple times then open each logged object, they all point to the same object in memory, whose value is the most current updated one.

It's a well known "issue", although the behaviour is a result of a design decision (see comments on the first link), and so isn't considered a bug by the dev team.

Easy workarounds are any means to get a non-object value of the object, so any serialisation method (e.g. console.log(JSON.stringify(foo));).

https://bugs.webkit.org/show_bug.cgi?id=35801
http://code.google.com/p/chromium/issues/detail?id=44720
http://code.google.com/p/chromium/issues/detail?id=50316

Sign up to request clarification or add additional context in comments.

8 Comments

Thanks. Guess it serves me right for not using Firebug!
Yea I'd have to agree it's kinda lame.. It makes console.log totally useless for tracing. But I guess you could use a traditional debugger for that stuff.
console.log(JSON.stringify(foo)); Should be fine for debugging.
I take this back. The calls aren't delayed, the log mechanism is reference-based, but the calls appear perfectly synchronous.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.