如果你开发过web app, 你一定熟悉 console.log(...),这个打印数据到开发者控制台的方法常用于调试,打印日志和测试。
运行console.log(console),你将看到在 console对象上面有很多属性方法。这篇文章简要概述10个贴心的技巧来提升你的日志使用体验。
Tables
console.table() 方法可以把对象/数组格式化成整齐的表格。
console.table({
'Time Stamp': new Date().getTime(),
'OS': navigator['platform'],
'Browser': navigator['appCodeName'],
'Language': navigator['language'],
});
Groups
使用console.group(),可将控制台的输出整合为可折叠起来的分组
你可以选择传入一个string类型的参数作为分组的标题。每个分组都可以在控制台中折叠或者展开。通过使用groupCollapsed可以使分组默认收起。你也可以嵌套子分组,但别忘了用groupEnd来结束每个分组。
以下的例子将创建一个分组,包含指定的信息。
console.group('URL Info');
console.log('Protocol', window.location.protocol);
console.log('Host', window.origin);
console.log('Path', window.location.pathname);
console.groupCollapsed('Meta Info');
console.log('Date Fetched', new Date().getTime());
console.log('OS', navigator['platform']);
console.log('Browser', navigator['appCodeName']);
console.log('Language', navigator['language']);
console.groupEnd();
console.groupEnd();
带样式的Log
浏览器支持为输入的log添加基本的CSS样式,比如颜色,字体,文本样式、大小,但浏览器对这个功能的支持并不稳定。
比如,运行以下代码
console.log(
'%cHello World!',
'color: #f709bb; font-family: sans-serif; text-decoration: underline;'
);
那么将输出为
看起来很不错,而且还有很多功能,比如改变字体,样式,背景,阴影,还有曲线...
这是一个类似的,我在控制台中使用的工具,代码在这里
Time
另一个经常使用的调试技术就是去调试执行时间,记录一个任务花费多长时间。该功能可以通过启动一个定时器console.time(),传入一个标识,并通过调用console.timeEnd()结束定时器,需要传入同样的标识。对于一个长时间运行的操作,也可以通过使用console.timeLog()添加标记。
console.time("concatenation");
let output = "";
for (var i = 1; i <= 1e6; i++) {
output += i;
}
console.timeEnd("concatenation");
concatenation: 1206ms - timer ended
还有个不标准的方法 console.timeStamp() ,他可以在性能标签里添加标记,你可以将代码中的部分与时间线中记录的其他事件(如绘制和布局事件)关联起来。
Assert
如果你只是需要在发生错误,或者特定条件判断下输出错误日志,那可以选各种使用console.assert(),该API在第一参为false的时候不会输出任何东西
第一参是一个用于检查条件的布尔值,后边0个或多个参数是你想打印输出的,最后一个参数是用于输出日志信息的。比如console.assert(false, 'Value was false')将会输出信息,因为第一参是 false。
const errorMsg = 'the # is not even';
for (let num = 2; num <= 5; num++) {
console.log(`the # is ${num}`);
console.assert(num % 2 === 0, { num }, errorMsg);
}
Count
是否曾经为了输出日志手动维护一个数字变量?console.count()会记录执行频次,或说程序多长时间进入一段代码。
如果你要管理多个计数器,你可以选择给定一个标识,让输出更清晰。计数器从1开始,可以在需要的时候用 console.countReset()重置,同样的也可传入一个标识参数。
以下代码将在数组迭代中将计数器每次加1,最终为8
const numbers = [1, 2, 3, 30, 69, 120, 240, 420];
numbers.forEach((name) => {
console.count();
});
以下展示了一个添加标识的计数器
如果参数不是标识而是传入一个值,那么对于不同条件的值将产生独立的计数器
console.count(NaN); // NaN: 1
console.count(NaN+3); // NaN: 2
console.count(1/0); // Infinity: 1
console.count(String(1/0)); // Infinity: 2
Trace
JavaScript中,我们常多层嵌套方法和对象,这时可以使用 console.trace()去遍历调用栈,看看到达指定点都有哪些方法被调用了。
可以选择传入参数作为输出的一部分。
Dir
如果打印一个大对象,可能不易读,console.dir()方法可以将大对象格式化为一个可折叠的树形结构。
以下展示了一个目录风格的输出
你也可以用类似方法console.dirxml输出基于XML、HTML的数据
Debug
在开发中可能有一些日志的设置,需要在开发环境中使用,但不希望用户看到。用console.debug()就可以做到这一点。这个功能和console.log完全一样,只不过大部分的打包系统都会忽略,或者在生产模式中被禁用。
日志级别
你也许注意到在浏览器控制台中有一些过滤器 (info, warnings 和 error),他们允许你改变日志的冗余度。你只需要使用如下不同的api来匹配过滤器:
console.info()- 信息级别的日志,通常是一个i图标和蓝色背景console.warn()- 警告,不重要的错误,通常是一个三角形感叹号和黄色背景console.error()- 影响功能的错误,通常是原型感叹号和红色背景
在Node.js中,在生产环境中运行时,不同的日志级别被写入不同的流,例如error() 将写入 stderr,而log将输出stdout,但在开发过程中,它们都将正常地显示在控制台中。
包含多个值的Log
console对象上大多函数接收多个参数,所以可以一次打印多条数据,或添加标识,比如: console.log('User: ', user.name);
但打印多个数据更简单的做法是使用对象解构object deconstructing, 比如有三个变量(x, y 和 z)你可以把他们包在大括号里,所以每个变量的名字和值会被输出,即console.log( { x, y, z } );
输出字符串类型日志
如果需要构建格式化的字符串来输出,可以使用c语言风格printf的格式说明符(specifier)来实现。
支持以下说明符:
%s- 字符串或转换为字符串的任何其他类型%d/%i- 整型%f- 浮点型%o- 使用最优(optimal)格式化%O- 使用默认格式化%c- 适应定制格式化 (更多信息)
如:
console.log("Hello %s, welcome to the year %d!", "Alicia", new Date().getFullYear());
// Hello Alicia, welcome to the year 2022!
当然,你也可以使用template literals来实现同样的功能,这对于比较短的字符可能看起来更清楚。
Clear
最后,如果你要寻找某个事件回调的输出,你也许希望能够先把控制台首次加载输出的所有日志清除掉,你可以使用console.clear(),这将清除所有日志,但不会重置任何数据。
通常也可能使去点击控制台的清除图标,或者使用搜索去过滤输入的文本。
特殊的浏览器方法
当直接在浏览器的控制台中运行代码时,可以访问几个方法的简写,这些方法在调试、自动化和测试非常有用。
最常用的如下:
$()-Document.querySelector()的缩写 (jQuery-风格!)$$()- 同上, 但会选择多个,即selectAll$_- 返回上一次表达式计算的值$0- 返回最近一次选择的DOM元素(在检查器里)$1...$4也可以获取最近选择的元素$x()- 使用 Xpath 选择DOM元素keys()和values()- Object.Keys(), Object.values(), 返回对象的keys或者valuescopy()- 复制到剪切板monitorEvents()- 给定事件被触发时运行命令- 对于一些常用的控制台命令,(比如
console.table()),你不需要输入console., 只需运行table()
还有更多的命令缩写, 这里是完整列表。
警告 只能在控制台中使用,代码中无法使用
更多
关于在控制台输出日志还有很多内容,更多信息可以参考MDN console Documentation 或者 Chrome Dev Console Docs。
这是一些最佳实践的说明:
- 定义一个lint规则,防止任何
console.log语句被合入到主分支 - 编写一个包装函数来处理日志记录,这样就可以根据环境启用/禁用调试日志,采用适当的日志级别,也能够按需进行格式化。而且在于与第三方日志服务集成时,只需在一个地方进行代码更新
- 不要输出敏感信息,浏览器日志可以被任何安装的插件获得,所以控制台不应该视为安全的环境
- 永远使用正确的日志级别(像
info,warn,error)在过滤或禁用时更方便 - 遵循一致的格式,方便日志被解析
- 用英语输出短的、有意义的日志信息
- 日志中添加上下文或者分类
- 不要过多使用,只输出有用的信息