console.log not standardized, so the behavior is rather vague and can easily be changed from release to release of developer tools. Your book is most likely out of date, as is my answer soon.
It does not matter for our code whether console.log asynchronous or not, it does not provide any callback or so; and the values you pass are always referenced and computed during the function call.
We really don't know what will happen then (well, we could, since Firebug, Chrome Devtools and Opera Dragonfly are all open source). The console will have to store the recorded values somewhere and display them on the screen. Rendering will occur exactly asynchronously (being limited by updates with a speed limit), as will future interactions with registered objects in the console (for example, extending the properties of an object).
Thus, the console can either clone (serialize) mutable objects that you wrote to the log, or store links to them. The first does not work very well with deep / large objects. In addition, at least the initial rendering in the console will probably show the “current” state of the object, that is, when it was registered - in your example, you see Object {} .
However, when you expand the object to further check its properties, it is likely that the console will only store a link to your object and its properties, and now when they are displayed, their current (already changed) state will be displayed. If you click on + , you can see the bar property in your example.
Here is a screenshot that was posted in the bug report to explain their “fix”:

Thus, some values can be referenced long before they are registered, and their assessment is rather lazy ("if necessary"). The most famous example of such a discrepancy is considered in the question : is the JavaScript console in Chrome lazy when evaluating arrays?
The workaround is to always capture serialized snapshots of your objects, for example using console.log(JSON.stringify(obj)) . This will only work for non-circular and fairly small objects. See also How can I change the default behavior of console.log in Safari? ,
The best solution is to use breakpoints for debugging when execution stops completely and you can check the current values at each point. Use logging only with serializable and immutable data.