原文地址:https://medium.com/@mattburgess/beyond-console-log-2400fdf4a9d8
作者:Matt Burgess
前言:工欲善其事,必先利其器。在浏览器调试器console中,除了console.log,还有其它不少操作可以输出值,这将是本篇文章中主要涉及的东西。
译文:
除了console.log之外,还有更多调试方法来输出JavaScript值。可能我看上去很明显要推荐调试器,但实际上并没有。
告诉JavaScript开发者他们应该使用浏览器的调试器看起来是一件很酷的事情,而且肯定有时间和地点来做这件事。但是很多时候您只想知道某一部分代码的执行结果或者这个变量是什么,而不是迷失在RxJS代码库或Promise内容库中。
尽管如此,虽然console.log占有一席之地,但是很多人都没有意识到console本身除了.log之外还有很多其他选项,合理使用这些功能可以使调试更容易,更快速,更直观。
console.log()
在旧而好的console.log中有着惊人的但是大家并不期望的功能。虽然大多数人这样来使用console:console.log(object),但您也可以执行console.log(object,otherObject,string),它会将它们全部记录下来。偶尔顺手。
除此之外,还有另一种格式:console.log(msg,values),这很像C或PHP中的sprintf。
console.log('I like %s but I do not like %s.', 'Skittles', 'pus');
预期输出:
> I like Skittles but I do not like pus.
常见的占位符有:%o(这是一个字母o,而不是零),它接受一个对象,%s接受一个字符串,%d是一个十进制或整数。
另一个有趣的是%c,但您的理解可能会有所不同,它实际上是CSS值的占位符。
console.log('I am a %cbutton', 'color: white; background-color: orange; padding: 2px 5px; border-radius: 2px');
有点奇怪的是,这些值会应用到后面任何内容上,没有“结束标记”,但您可以将它变得像这样。
这不是那么优雅,也不是特别有用,而且,这也不是一个真正的按钮。
这真的有用吗?
console.dir()
在大多数情况下,console.dir()函数非常类似于log(),虽然它看起来有点不同。
我们展开小箭头将会显示确切对象的详细信息,这也可以从console.log中看到。但是当您查看元素时,事情就会发生很大的变化而且变得更有趣。
let element = document.getElementById('2x-container');
这是.log的输出:
我展开一些元素,可以清楚地显示DOM,并且我们可以浏览它。但是console.dir(element)给了我们一个惊人的不同输出:
这是一种更加客观的方式来查看元素,有时候这就是您真正想要的东西,有点像是检查元素。
console.warn()
console.warn()可能是最明显的直接替换log()的方式,您用完全相同的方式使用它,唯一真正的区别是输出颜色是黄色。具体来说,输出处于警告级别而不是信息级别,因此浏览器将稍微区分一下,这对混乱的输出有着明显的益处。
但是,这还有一个更大的好处。因为输出是警告而不是信息,所以您可以过滤掉所有console.log而只是保留console.warn,这对于偶尔会在浏览器中输出大量无用log的应用程序尤其有用,清除没用的信息可以让您更轻松地看到想要的信息。
console.table()
令人惊讶的是,这个方法并怎么为人所知,但是console.table()函数旨在以比抛出原始对象数组更简洁的方式显示表格数据。例如,下面一个数据列表:
const transactions = [{id: "7cb1-e041b126-f3b8", seller: "WAL0412", buyer: "WAL3023", price: 203450, time: 1539688433},{ id: "1d4c-31f8f14b-1571", seller: "WAL0452", buyer: "WAL3023", price: 348299, time: 1539688433},{ id: "b12c-b3adf58f-809f", seller: "WAL0012", buyer: "WAL2025", price: 59240, time: 1539688433}];
如果我们使用console.log来输出上面的内容,我们会得到一些不太有用的输出:
▶ (3) [{…}, {…}, {…}]
小箭头可以让您点击并打开数组,但这并不是我们想要的“一目了然”。
因此console.table(data)的输出更有帮助一些。
第二个参数是可选的,能够筛选出您想要的列,默认为所有列,但我们也可以这样做。
> console.table(data, ["id", "price"]);
我们得到输出只会显示id和price。这适用于过大的object,而且不需要什么细节,索引列是自动创建的,并不会消失。
这里要注意的是这是乱序的 - 最右边的列标题上的箭头显示了原因。我能够点击该列进行排序,非常方便的找到这一列的最大值或最小值,或者只是找到数据的不同处。顺便说一句,该功能与仅显示一些列无关,它始终可用。
console.table()只能处理最多1000行,因此可能不适合所有数据集。
console.assert()
有一个有用的函数经常忽视掉,那就是assert(),assert()与log()相同,但仅在第一个参数为false的情况下,如果第一个参数为真,它什么都不做。
这对于有循环(或几个不同的函数调用)并且只有一个特定行为的情况特别有用。基本上它和这样做是一样的:
if (object.whatever === 'value') { console.log(object);}
需要澄清的是,当我说“相同”时,我应该更好地说这与做到这一点恰恰相反,因此上述代码您需要反转条件。
让我们假设上面的一个值是在时间戳中使用null或0,这会搞砸我们的格式化日期代码。
console.assert(tx.timestamp, tx);
当与任何有效的对象一起使用时,它只是跳过去。但是破坏的那个会触发我们的日志记录,因为时间戳是0或null,这是假值。
有时我们想要更复杂的情况。例如,我们已经看到用户WAL0412的数据存在问题,并且只想显示来自它们的数据,这是直观的解决方案:
console.assert(tx.buyer === 'WAL0412', tx);
这看起来是对的,但其实并不起作用。请记住,条件必须是假的...我们想要的是断言,而不是过滤。
console.assert(tx.buyer !== 'WAL0412', tx);
这才是我们想要的,用户不是WAL0412的任何交易在该条件下都是正确的,只留下WAL0412用户。
有些情况下,console.assert()并不是那么特别有用,但在特定情况下它可以是一个不错的解决方案。
console.count()
count只是扮演一个计数器的角色,可选择作为一个命名计数器。
这并不是什么有用的代码,有点抽象,此外,我也不打算演示isPrime函数,只是假装它有效。
我们得到的应该基本上是一个列表:
等等,这可能在您只是转储索引的情况下很有用,或者您希望保留一个(或多个)运行计数。您也可以不带参数来使用console.count(),这样做会将其称为默认值。如果您愿意,还可以使用相关的console.countReset()来重置计数器。
console.trace()
这很难用简单的数据进行演示,它擅长的地方是帮助您在一个类或库中找出真正导致issue的调用。举个例子,可能有12个不同的组件调用服务,但其中一个组件没有正确设置依赖关系:
在这里单独使用console.log()会告诉我们传入的dataLib是什么,而不是在哪里。但是,堆栈跟踪将非常清楚地告诉我们问题是Dashboard.js,我们可以看到它是new CupcakeService(false)导致的错误。
console.time()
console.time()是一个跟踪操作所用时间的专用函数是,它是跟踪JavaScript执行所用微时间的更好方法。
这是一种老式的方法,我还应该也指上面的console.log。很多人都没有意识到您可以在那里使用模板字符串和插值,但您可以做,且有所帮助。
所以让我们现代化以上代码:
现在我们不再需要做任何数学运算或设置临时变量。
console.group()
现在我们可能在控制台输出中最复杂和最先进的领领域。Group让您......好吧,是分组,特别是它可以让您嵌套东西。它擅长的地方在于显示代码中存在的结构。
这又是一种简陋的输出,您可以在这里看到输出。
虽然不是很有用,但您可能会看到其中一些是如何组合在一起的。
这是需要很多工作量,并且很多用于调试信息的代码,可能不是那么有用,但它仍然是一个有趣的想法,您能够通过它使您的日志记录更加清晰。
最后要指出的是console.groupCollapsed,在功能上,它与console.group相同,但它没有关闭,而且它并没有得到很好的支持,但如果你有一大堆废话,你可能想要默认隐藏,那么它是一个选择。
结论
这里没有太多结论,所有这些方法都可能有用,如果你可能只需要一点点console.log,但实际上并不需要调试器。
可能最有用的是console.table,但所有其他方法也都有自己的位置。我是console.assert的粉丝,因为我们有时候想调试一些东西,但只能在特定情况下调试。
后记
在平时工作中可能使用console.log最多,其它方法并不是那么常用,但是在一些情况下也可以尝试去使用这些调试方法,能够让自己的调试信息更加清晰明了,方便自己的调试过程。