【问题标题】:Bug in console.log? [duplicate]console.log 中的错误? [复制]
【发布时间】:2012-06-22 13:01:14
【问题描述】:

可能重复:
Is Chrome's JavaScript console lazy about evaluating arrays?

我尝试以下代码:

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

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

【问题讨论】:

  • 您使用的是哪个版本的 chrome?在哪个平台上?我试图在我的控制台中运行你的代码,我得到了正确/合乎逻辑的答案
  • 你是如何用setTimeout 来称呼它的?我也试过了,得到了预期的结果。
  • 这不是错误,而是功能! Console.log 保留对记录对象的引用,因此您可以在运行时预览对象。如果您更改了对象的属性,那么此更改自然也会显示在此实时预览中。你可以尝试浏览对象,看看它的“层次”是无限深的,所以不可能缓存它。

标签: javascript firefox google-chrome console javascript-debugger


【解决方案1】:

我的观点是,这是一个非常令人讨厌的“功能”,我真的希望我可以关闭它,它使调试成为一场噩梦,不知道什么时候可能更新了对象,同时试图建立确切的对象在代码中的给定点状态。该功能可能对“观察点”等有用,但不适用于所谓的“日志”(线索就在名称中)。

考虑这个代码片段:

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'

【讨论】:

  • 废话,我以为我有一台可以在值更新之前更新值的量子计算机!
【解决方案2】:

这是一个known bug (50316),因为人们在报告之前没有查看错误跟踪器,所以一次又一次地被报告:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

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

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

      【讨论】:

        【解决方案5】:

        我在最新版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-06-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-09
          • 2017-04-10
          • 2014-12-14
          • 1970-01-01
          相关资源
          最近更新 更多