你不知道的 console

1,100 阅读5分钟

每个前端开发工程师都是 javascript console 对象的重度用户,console 贯穿了真个开发周期,从开发调试到 bug 定位,或者性能分析,甚至追踪线上问题。但是大部分同学可能只会用 console.log / console.dir / console.time / console.tabel 这三四个方法,console 还有大把的 API 等待我们去发掘,熟练使用 console 保证能让你的开发效率蹭蹭提升。

首先让我们再认识下 console

console 对象提供对浏览器调试控制台的访问。console 挂载在 window 对象上,ECMAScript 中并没有规定 console 该如何实现,因为它不属于 javascript 的语言标准。每个浏览器都有自己的实现,并不约而同的把它挂载到 window 对象上。所以 console 对象的方法并不是每个浏览器都会实现,行为也可能会有略微差异。

接下来让我们依次介绍 console 的 API

console.log

console.log(obj1[, obje2, obje3, ... objN])

按照参数传入的顺序打印一个或者多个变量。需要注意的是,如果打印的是 Object / Array / Function 等非基本类型,在控制台显示的是该变量的引用,也就是说后续对变量的修改也会体现在控制台。

如上图,log 打印 4 个值,log 后立刻修改 obj ,arr ,控制台结果如下

咦!并没有展示出修改后的结果呀,别急,点开那个小 ▶ 

console 初使打印的是执行到 console.log 语句时的变量值,虽然是引用类型,但是控制台并不会实时追踪值的变化,只有用户主动触发 ▶ (查看详情)才会展示变量的当前值。 后续值的更改不会再反应到控制台,也就是说一旦查看详情,控制台对变量的跟踪就“断开”了。

如果就想打印某个 object 执行到 console 的当前值怎么办?

console.log(JSON.parse(JSON.stringify(object)))

深度克隆 object (推荐)

console.log 方法还需要提一嘴的是它在打印 DOM 对象的特殊性,log 方法会将 DOM 对象当作一个 HTML-like tree 处理,在控制台打印出当前 DOM 树,但是 console.dir 方法会把 DOM 对象当作一个普通 JS 对象处理。

(一个 log 方法一不小心就讲了这么多,后面我们加快讲解 API 的节奏,更详细的用法,大家再自行 google)

console.dir

console.dir(obj)

在控制台打印出 obj 带有三角形的层次结构列表,可查看子对象的内容。

跟 log 方法的区别是不显示简略信息,只显示一个 ▶ 和对象参数的 constructor 

 - 

console.error

console.error(obj1[, obje2, obje3, ... objN])

打印出错误信息,一般底色为红色, 浏览器的 JS 报错用的就是 console.error 。

并会展示错误位置的调用栈。

console.warn

console.warn(obj1[, obje2, obje3, ... objN])

与 console.error 类似,等级比 error 低,一般底色为黄色;

console.clear

清除 console 控制台的信息,这个方法用得不多,毕竟控制台本身就有一个清空信息的 button。它的应用场景是,如果框架或者类库本身的 error / warn 信息过多,或者协同开发过程中他人的 log 很多,在你想打的 log 之前调用 clear() ,暂时清空这些干扰信息。

console.time / console.timeEnd

console.time(label) / console.timeEnd(label)

这个是我本人最喜欢的一组 API,打印出 time 到 timeEnd 之间 JS 执行耗时

console.time 支持多组同时存在,可以互相穿插、包含。

现在浏览器中的 Performance 工具很强大,但是很难分析指定某几行代码的性能。再加上现在很多 Web APP 使用 React 、 VUE 等类库,调用层层嵌套,很难追踪性能问题。利用 console.time 就可以方便的切割一个文件的所有代码,利用二分法逐步分析到某一行的代码执行耗时。

console.timeLog

console.timeLog(label)

是 time / timeEnd 方法的补充。可以打印出 time 开始到 timeLog 之间的执行耗时

console.trace

trace 方法可以用来展示函数的调用链,不知道某个函数是由哪里触发的,试试这个方法,真的很好用。

 - 

console.assert

console.assert(assertion, obj1[, obj2, ..., objN])

断言 assertion 是否为 false,如果是,打印后面传入的参数。这个方法一般用来判断某些变量与预期不符时打印异常。

console.count

console.count([label])

用于计数,记录 count([label]) 被调用的次数。如果我们想打印出某个函数被调用的次数,不需要再定义一个变量 count ➡️ count++ ➡️ console.log(count) 这种方式,直接使用 count 方法即可。

 - 

console.countReset

console.countReset([label])

重置计数为 0,可配合 count 使用。

console.debug

传参及打印方式跟 .log 方法相同,唯一不同的是在控制台的显示级别,大部分浏览器是默认不显示 debug 内容的,需要主动开启。如 Chrome 浏览器勾选 Verbose 才会显示 debug 方法打印的内容。

console.group / console.groupEnd

console.group([label]) / console.groupEnd([label])

将打印内容分组,分组可以嵌套成树形结构。

点击 ▶ 可以展开收起分组,在打印内容非常多,而且层次清晰的时候非常适合使用 group / groupEnd 方法。
另外, group 方法可以使用 groupCollapsed 方法替代,前者默认打开层次结构,后者默认关闭。

console.profile / console.profileEnd

开始 / 结束 Chrome 控制台 JavaScript Profiler 的记录,FireFox 是开始性能记录,但并不会在调用 profileEnd 时结束,需要主动在控制台输入 profileEnd。
在 Chrome 中可以使用 time / timeEnd 代替。在 FireFox 的试用场景是,程序运行到某一步开始自动记录性能,某些情况下比手动开启性能监控更精准。

console.table

console.table(obj)

以表格的形式展示 obj ,视觉上更直观,美观。缺点是不能展示太多的层次。

在表格的下方作为补充,也会以 .log 方法的形式展示 obj 。


好了,console API 已经介绍完了。合理的选择 console 的方法可以让我们的控制台日志更清晰,有调理。还可以进行性能分析,函数调用栈分析,提升我们的开发 / debug 效率。

PS:

console.log 方法还可以自定义样式,插入图片等等,玩出很多花样来,网上介绍自定义 console 样式的文章很多,我不再赘述。