5

可能重复:
Chrome 的 JavaScript 控制台是否懒于评估数组?

我尝试以下代码:

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);

结果很奇怪:

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

item-1

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

item-2

但是 - 如果我在一段时间后执行第二部分(使用 setTimeout),并展开第一个对象,我做对了,即:

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

item-1

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

item-2

我觉得分享它很重要,因为我认为一个人可能会浪费很多时间来试图理解他的代码中的问题。如果有人提到了一个开放的错误或其他东西 - 请回复这张票。谢谢!

4

5 回答 5

5

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'
于 2012-07-18T10:27:26.833 回答
3

这是一个已知的错误 (50316),它会一次又一次地被报告,因为人们在报告之前没有查看 bugtracker:

可悲的是,没有关于是否/何时解决此问题的信息。在那之前,您需要先克隆对象,然后再将它们传递给console.log().

于 2012-06-20T12:13:55.663 回答
0

这是某些浏览器中控制台日志的已知问题/功能。

当您记录某些内容时,它可能不会立即转换为文本格式。如果日志存储了对您记录的对象的引用,那么当它实际显示在日志中时,它将转换为文本格式。

这样做的好处是记录某些内容对性能的影响非常小,直到您实际打开日志窗口来显示日志。

即使您在运行代码时打开了日志窗口,在您的函数运行时也不会发生更新(因为 Javascript 是单线程的),因此控制台窗口将显示函数末尾的值,当窗口更新时。

于 2012-06-20T11:55:45.190 回答
0

在我看来,这更像是一种比赛条件。由于您仅传递对 的引用console.log(),因此它所引用的值可能在实际记录时已更改值。然后,当您使用 setTimeout() 时,该值会在记录后发生变化。与其传递对 的引用console.log(),不如传递值的克隆。

于 2012-06-20T11:49:02.557 回答
0

我在最新版本的 Chrome 20.0.1132.57 m 上对这个“问题”做了一些实验。总结要点:-

  • 执行代码时,console.log() 使用 as "> Object" 打印对对象的引用
  • 单击三角形时显示对象的状态,与执行 console.log() 的代码行无关
  • 如果要打印当前状态的对象,请打印一个克隆console.log(JSON.parse(JSON.stringify(obj)));

您可以使用这段代码在您自己的浏览器上进行测试:

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 ) ; };
于 2012-07-25T09:51:23.317 回答