Bug in console.log? [duplicate]

2019-01-19 20:58发布

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

I try the following code:

var myList = new Object();
var item   = new Object();
item.text  = "item-1";
myList[3]  = item;

console.log(myList);
console.log(myList[3].text);

// Assign another object to the same entry
var item2   = new Object();
item2.text  = "item-2";
myList[3]  = item2;

console.log(myList);
console.log(myList[3].text);

The result is quite odd:

* Object
  * 3: Object
      text: "item-2"

item-1

* Object
  * 3: Object
      text: "item-2"

item-2

BUT - if i execute the second part after some time (using setTimeout), and unfold the first object, I get it right, i.e.:

* Object
  * 3: Object
      text: "item-1"

item-1

* Object
  * 3: Object
      text: "item-2"

item-2

I find it important to share it, since I think one can waste a lot of time trying to understand what's wrong in his code. And if somebody has some reference to an open bug or something - please reply this ticket. Thanks!

5条回答
smile是对你的礼貌
2楼-- · 2019-01-19 21:11

This is a known problem/feature with the console log in some browsers.

When you log something, it may not immediately be turned into text format. If the log stores a reference to the object that you log, it will be turned into text format when it's actually shown in the log.

This has the advantage that logging something has a very small impact on performance, until you actually open the log window to show the log.

Even if you have the log window open while you run the code, there is no updates happening while your function is running (as Javascript is single threaded), so the console window will show the values as they are at the end of the function, when the window is updated.

查看更多
做个烂人
3楼-- · 2019-01-19 21:12

Sounds to me more like a race condition than anything else. Since you are only passing a reference to console.log(), the value it refers it has likely changed value by the time it is actually logged. Then when you use setTimeout(), the value changes after it has been logged. Instead of passing a reference to console.log(), pass a clone of the value.

查看更多
SAY GOODBYE
4楼-- · 2019-01-19 21:26

I have done some experiments with this "problem" on the latest version of Chrome 20.0.1132.57 m.To summarize the key points :-

  • console.log() prints a reference to the object with as "> Object" when the code is executed
  • The state of the object when you click on the triangle is displayed, irrespective of the line of code where the console.log() is executed
  • If you want to print the object in its current state, print a clone console.log(JSON.parse(JSON.stringify(obj)));

You could use this bit of code to test this on your own browser:

window.onload = function() {chto = {a : 10, b : 20};
console.log('Open this object after 5 seconds')
console.log(chto);
console.log('Open this object before 5 seconds')
console.log(chto);
console.log('Console of the cloned object')
console.log(JSON.parse(JSON.stringify(chto)));
setTimeout(function(){ console.log('5 seconds up'); chto['b'] = 30; },5000 ) ; };
查看更多
聊天终结者
5楼-- · 2019-01-19 21:28

My view is that this is a horrendously irritating 'feature' that I really wish I could turn off, it makes debugging a nightmare, not knowing at which point in time something may have updated an object, whilst trying to establish exact object state at a give point in the code. The feature could be useful for 'watch points' etc, but not in something called a 'LOG' (the clue is in the name).

Consider this code fragment:

var person = {'name':'Tom'};
console.log( person);  //output the entire object variable
person.name = 'Thomas';
//the output is an object, whose 'name' value is 'Thomas', even though the log statement was placed before the value was changed to 'Thomas'.

AND THEN:

var person = {'name':'Tom'};
console.log( person.name);    //changed to output a string variable
person.name = 'Thomas';
//the output here, however, has not dynamically updated and correctly outputs 'Tom'
查看更多
对你真心纯属浪费
6楼-- · 2019-01-19 21:34

this is a known bug (50316) that gets reported again and again because people don't take a look at the bugtracker before reporting:

sadly, theres no information about if/when this will get solved. until that moment, you'll need to clone objects before passing them to console.log().

查看更多
登录 后发表回答