console.log有bug吗?

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

我认为分享这个很重要,因为我认为一个人在尝试理解他的代码有什么问题时可能会浪费很多时间。如果有人对某个已知漏洞或其他内容有参考资料,请回复此工单。谢谢!

2
你使用的是哪个版本的Chrome?在哪个平台上?我尝试在我的控制台中运行你的代码,我得到了正确/逻辑上的答案。 - j_freyre
您是如何使用 setTimeout 准确调用它的?我也尝试了一下,并获得了预期的结果。 - jsalonen
这不是一个错误,而是一个特性! Console.log 保留了已记录对象的引用,因此您可以在运行时预览对象。如果您更改了对象的属性,则自然会在此实时预览中显示此更改。 您可以尝试浏览对象,以查看其“层次结构”是无限深的,因此无法缓存它。 - average Joe
5个回答

5
我的观点是,这是一个极其烦人的“特性”,我真希望能关闭它,因为它使得调试变成了一场噩梦。我们无法知道在哪个时间点上某个对象可能会更新,同时又要确定代码中确切的对象状态。这个功能可以用于“监视点”等方面,但不应该出现在名为“LOG”的东西里(提示已经在名称中了)。
考虑以下代码片段:
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'.

然后:
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'

1
糟糕,我以为我有一台量子计算机可以在更新值之前更新它们! - FlavorScape

3

这是一个已知的错误 (50316),人们在报告之前没有查看错误跟踪器,所以一遍又一遍地报告:

不幸的是,目前没有关于何时解决此问题的信息。在那之前,您需要在将对象传递给console.log()之前克隆它们。


0
听起来更像是竞争条件。由于您只传递了对console.log()的引用,它所引用的值很可能在实际记录时已经改变了。然后当您使用setTimeout()时,该值在记录后发生了更改。不要传递console.log()的引用,而是传递该值的克隆。

0

这是一些浏览器控制台日志的已知问题/特性。

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

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

即使你在运行代码时打开了日志窗口,由于Javascript是单线程的,所以在函数运行时没有更新发生(除非你手动刷新),因此当窗口更新时,控制台窗口将显示函数结束时的值。


0

我已经在最新版本的Chrome 20.0.1132.57 m上对这个“问题”进行了一些实验。总结关键点如下:

  • 当代码被执行时,console.log()会打印一个对象的引用,格式为"> 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 ) ; };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接