【译】console.log()的一些贴心技巧

86 阅读3分钟

原文dev.to/lissy93/fun…

如果你开发过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'],
});

image.png

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();

image.png

带样式的Log

浏览器支持为输入的log添加基本的CSS样式,比如颜色,字体,文本样式、大小,但浏览器对这个功能的支持并不稳定。

比如,运行以下代码

console.log(
  '%cHello World!',
  'color: #f709bb; font-family: sans-serif; text-decoration: underline;'
);

那么将输出为

image.png

看起来很不错,而且还有很多功能,比如改变字体,样式,背景,阴影,还有曲线...

image.png

这是一个类似的,我在控制台中使用的工具,代码在这里

image.png

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

image.png

还有个不标准的方法 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);
}

image.png

Count

是否曾经为了输出日志手动维护一个数字变量?console.count()会记录执行频次,或说程序多长时间进入一段代码。

如果你要管理多个计数器,你可以选择给定一个标识,让输出更清晰。计数器从1开始,可以在需要的时候用 console.countReset()重置,同样的也可传入一个标识参数。

以下代码将在数组迭代中将计数器每次加1,最终为8

const numbers = [1, 2, 3, 30, 69, 120, 240, 420];
numbers.forEach((name) => {
  console.count();
});

以下展示了一个添加标识的计数器

image.png

如果参数不是标识而是传入一个值,那么对于不同条件的值将产生独立的计数器

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()去遍历调用栈,看看到达指定点都有哪些方法被调用了。

image.png

可以选择传入参数作为输出的一部分。

Dir

如果打印一个大对象,可能不易读,console.dir()方法可以将大对象格式化为一个可折叠的树形结构。

以下展示了一个目录风格的输出

image.png

你也可以用类似方法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, 比如有三个变量(xy 和 z)你可以把他们包在大括号里,所以每个变量的名字和值会被输出,即console.log( { x, y, z } );

image.png

输出字符串类型日志

如果需要构建格式化的字符串来输出,可以使用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或者values
  • copy() - 复制到剪切板
  • monitorEvents() - 给定事件被触发时运行命令
  • 对于一些常用的控制台命令,(比如 console.table()),你不需要输入console., 只需运行 table()

还有更多的命令缩写, 这里是完整列表

警告 只能在控制台中使用,代码中无法使用

更多

关于在控制台输出日志还有很多内容,更多信息可以参考MDN console Documentation 或者 Chrome Dev Console Docs

这是一些最佳实践的说明:

  • 定义一个lint规则,防止任何console.log语句被合入到主分支
  • 编写一个包装函数来处理日志记录,这样就可以根据环境启用/禁用调试日志,采用适当的日志级别,也能够按需进行格式化。而且在于与第三方日志服务集成时,只需在一个地方进行代码更新
  • 不要输出敏感信息,浏览器日志可以被任何安装的插件获得,所以控制台不应该视为安全的环境
  • 永远使用正确的日志级别(像 infowarnerror)在过滤或禁用时更方便
  • 遵循一致的格式,方便日志被解析
  • 用英语输出短的、有意义的日志信息
  • 日志中添加上下文或者分类
  • 不要过多使用,只输出有用的信息