踩坑系列之[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 汉字对应表的网把 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里。