踩坑系列之[1]-诡异的console

console调试利器

在浏览器开发中,最简单的调试工具,应该就是代码中打印日志了,使用console对象可以进行打印日志、时间记录甚至assert断言。

除了我们常用的log方法,其实还有很多其他好用的调试方法,如trace,time,profile性能,assert,count等等。 具体请看:
http://hao.jser.com/archive/4202/
https://segmentfault.com/a/1190000002511877

console.log和console.dir的用法

两者在chrome里几乎没有区别,但有一个对于我们有点价值的区别,就是打印dom对象的时候:

  • 在 Chrome 中打印 DOM 元素时,console.log() 会将 DOM 元素以 HTML 的形式输出,(方便你用鼠标进行element定位)
  • 而 console.dir() 则会以 JS 对象的形式输出

console.log和console.dir
这个在firefox表现很明显, dir的话能够查看到一个对象的各个属性结构,可以自由折叠。 而log的话是以字符串快照的形式输出了那个对象。你去点击时不会再次计算了。
使用console.dir的截图如下:,可以看到我把a后面改成了false,结果console.dir在火狐狸两次打印都是false。(不过火狐很聪明的在第一行给你打印了使用console时候的快照, 一般这才是我们想要的,我们就想看这句代码执行时候的a,那个时候应该是true)

而chrome在使用console.log和console.dir时就没有区别了, 都是打印出一个对象,并且可以让你点击折叠。 这就导致你看里面属性的时候就会延迟计算。
所以chrome里有个坑。
当然chrome里打印常量时也有点区别,比如打印console.log(/foo/) 这种正则,log就会给他弄成字符串输出,而dir会搞成一个可点击的对象。 输出dom对象时,dir也会输出js对象,而log会输出页面dom 字符串,而且可以鼠标调试dom。

参考:http://stackoverflow.com/questions/11954152/whats-the-difference-between-console-dir-and-console-log

一个坑

console.log打印对象时有个坑。比如 a = {b:1} ,你先console.log打印他,然后把b改成2
情况1: 因为chrome浏览器开发人员工具里,你会看到他显示b:1,但你点击箭头展开这个对象时,他会实时计算这个对象的值。看到的是2
(在对象旁边的小叹号里有说明)

情况2: 还有当你网页运行完成后,你再F12打开控制台的话。 无论怎样,控制台里显示的都是运算后的a的值,b就是2.

所以在大部分情况下, 你 这个对象会计算出now这个对象的current状态。
这就导致你本来想看你写console.log这句代码的时候这个对象的状态,结果他给你显示的是现在这一时刻该对象的状态。

解决方法: 转成json串打印
目标:我们希望log函数可以查看对象打印时当时的状态,dir可以显示对象最终的状态,

备注:nodejs中不存在这种问题,因为node中打印的日志到标准输出流,已经以字符串的形式展现,不会再发生变化。

至于浏览器为什么这么做:

作者:李天昭
链接:https://www.zhihu.com/question/20507212/answer/15323711
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

看了问题, 随手在chrome里试了一下,发现结果确实很诡异,我陷入了深深的思考中……
看另一段代码

这是我在chrome dev bar里敲的。
第一次使用console.log的时候期望输出一个空对象;结果却不是这样。
chrome dev bar的问题

  1. console.log()传入的参数如果指向一个可变对象(数组、对象),那么它会默默地记录下这个引用;
  2. 在你查看这个输出结果的时候,才会读取这个对象,并把相关属性和值显示出来。
    这个“功能特性”的好处是对于正在运行的程序性能影响最小化(因为输出时只记录引用,而不去寻找一个对象的所有属性,肯定减少了计算时间);坏处嘛,就是在调试一些对象的时候会陷入蛋疼的境地。
    解决方法
  3. 虽然我已经不爱用Firebug了,但是它的控制台却没这问题—dir可以打印快照;
  4. 在chrome中曲线救国:
    console.log(JSON.parse(JSON.stringify(obj)));

解决

我搞了个库:在https://github.com/cuiyongjian里。