灵活使用 console 让 js 调试更简单

论坛 期权论坛 期权     
前端大全   2019-6-10 04:03   3021   0
(给前端大全加星标,提升前端技能)
作者:前端小智
https://segmentfault.com/a/1190000018756503#articleHeader9
Web开发最常用的高度就是
  1. console.log
复制代码
,虽然
  1. console.log
复制代码
占有一席之地,但很多人并没有意识到
  1. console
复制代码
本身除了基本
  1. log
复制代码
方法之外还有很多其他方法。 适当使用这些方法可以使调试更容易,更快速,更直观。


[h1]console.log()[/h1]在
  1. console.log
复制代码
中有很多人们意想不到的功能。虽然大多数人使用
  1. console.log(object)
复制代码
来查看对象,但是你也可以使用
  1. console.log(object, otherObject, string)
复制代码
,它会把它们都整齐地记录下来,偶尔也会很方便。
不仅如此,还有另一种格式化的:
  1. console.log(msg, values)
复制代码
,这很像 C 或 PHP 中的
  1. sprintf
复制代码

  1. console.log('I like %s but I do not like %s.', 'Skittles', 'pus');
复制代码
会像你预期的那样输出:
  1. > I like Skittles but I do not like pus.
复制代码
常见的占位符
  1. %o
复制代码
(这是字母o,不是0),它接受对象,
  1. %s
复制代码
接受字符串,
  1. %d
复制代码
表示小数或整数。


另一个有趣的是
  1. %c
复制代码
,这可能与你所想不太相同,它实际上是CSS值的占位符。使用%c占位符时,对应的后面的参数必须是CSS语句,用来对输出内容进行CSS渲染。常见的输出方式有两种:
  1. 文字样式、图片输出
复制代码

  1. console.log('I am a %cbutton', 'color: white; background-color: orange; padding: 2px 5px; border-radius: 2px');
复制代码


它并不优雅,也不是特别有用。当然,这并不是一个真正的按钮。


它有用吗? 恩恩恩。
console.dir()
在大多数情况下,
  1. console.dir()
复制代码
的函数非常类似于
  1. log()
复制代码
,尽管它看起来略有不同。


下拉小箭头将显示与上面相同的对象详细信息,这也可以从
  1. console.log
复制代码
版本中看到。当你查看元素的结构时候,你会发现它们之间的差异更大,也更有趣。
  1. let element = document.getElementById('2x-container');
复制代码
使用
  1. console.log
复制代码
查看:


打开了一些元素,这清楚地显示了 DOM,我们可以在其中导航。但是
  1. console.dir(element)
复制代码
给出了更加方便查看 DOM 结构的输出:
这是一种更客观地看待元素的方式。有时候,这可能是您真正想要的,更像是检查元素。


[h1]console.warn()[/h1]可能是最明显的直接替换
  1. log()
复制代码
,你可以以完全相同的方式使用
  1. console.warn()
复制代码
。 唯一真正的区别是输出字的颜色是黄色的。 具体来说,输出处于警告级别而不是信息级别,因此浏览器将稍微区别对待它。 这具有使其在杂乱输出中更明显的效果。


不过,还有一个更大的优势,因为输出是警告而不是信息,所以你可以过滤掉所有
  1. console.log
复制代码
并仅保留
  1. console.warn
复制代码
。 这对于偶尔会在浏览器中输出大量无用废话的应用程序尤其有用。 清除一些无用的信息可以让你更轻松地看到你想要的输出。
console.table()
令人惊讶的是,这并不是更为人所知,但是
  1. console.table()
复制代码
函数旨在以一种比仅仅转出原始对象数组更整洁的方式显示表格数据。
例如,这里有一个数据列表。
  1. const data = [{
复制代码
  1. id: "7cb1-e041b126-f3b8",
复制代码
  1. seller: "WAL0412",
复制代码
  1. buyer: "WAL3023",
复制代码
  1. price: 203450,
复制代码
  1. time: 1539688433
复制代码
  1. },
复制代码
  1. {
复制代码
  1. id: "1d4c-31f8f14b-1571",
复制代码
  1. seller: "WAL0452",
复制代码
  1. buyer: "WAL3023",
复制代码
  1. price: 348299,
复制代码
  1. time: 1539688433
复制代码
  1. },
复制代码
  1. {
复制代码
  1. id: "b12c-b3adf58f-809f",
复制代码
  1. seller: "WAL0012",
复制代码
  1. buyer: "WAL2025",
复制代码
  1. price: 59240,
复制代码
  1. time: 1539688433
复制代码
  1. }];
复制代码
  1. [/code]如果我们使用 [code]console.log
复制代码
来输出上面的内容,我们会得到一些非常无用的输出:
  1. (3) [{…}, {…}, {…}]
复制代码
点击这个小箭头可以展开看到对象的内容,但是,它并不是我们想要的“一目了然”。
但是
  1. console.table(data)
复制代码
的输出要有用得多。


第二个可选参数是所需列的列表。显然,所有列都是默认值,但我们也可以这样做:
  1. > console.table(data, ["id", "price"]);
复制代码


这里要注意的是这是乱序的 - 最右边的列标题上的箭头显示了原因。 我点击该列进行排序。 找到列的最大或最小,或者只是对数据进行不同的查看非常方便。 顺便说一句,该功能与仅显示一些列无关,它总是可用的。
  1. console.table()
复制代码
只能处理最多1000行,因此它可能不适合所有数据集。
console.assert()
  1. assert()
复制代码
  1. log()
复制代码
是相同的函数,
  1. assert()
复制代码
是对输入的表达式进行断言,只有表达式为false时,才输出相应的信息到控制台,示例如下:
  1. var arr = [1, 2, 3];
复制代码
  1. console.assert(arr.length === 4);
复制代码


有时我们需要更复杂的条件句。例如,我们已经看到了用户
  1. WAL0412
复制代码
的数据问题,并希望仅显示来自这些数据的事务,这是直观的解决方案。
  1. console.assert(tx.buyer === 'WAL0412', tx);
复制代码
这看起来不错,但行不通。记住,条件必须为
  1. false
复制代码
,断言才会执行,更改如下:
  1. console.assert(tx.buyer !== 'WAL0412', tx);
复制代码
与其中一些类似,
  1. console.assert()
复制代码
并不总是特别有用。但在特定的情况下,它可能是一个优雅的解决方案。
console.count()
另一个具有特殊用途的计数器,count只是作为一个计数器,或者作为一个命名计数器,可以统计代码被执行的次数。
  1. for(let i = 0; i < 10000; i++) {
复制代码
  1. if(i % 2) {
复制代码
  1. console.count('odds');
复制代码
  1.   }
复制代码
  1. if(!(i % 5)) {
复制代码
  1. console.count('multiplesOfFive');
复制代码
  1.   }
复制代码
  1. if(isPrime(i)) {
复制代码
  1. console.count('prime');
复制代码
  1.   }
复制代码
  1. }
复制代码
这不是有用的代码,而且有点抽象。这边也不打算演示
  1. isPrime
复制代码
函数,假设它是成立的。
执行后我们会得到一个列表:
  1. odds: 1
复制代码
  1. odds: 2
复制代码
  1. prime: 1
复制代码
  1. odds: 3
复制代码
  1. multiplesOfFive: 1
复制代码
  1. prime: 2
复制代码
  1. odds: 4
复制代码
  1. prime: 3
复制代码
  1. odds: 5
复制代码
  1. multiplesOfFive: 2
复制代码
  1. ...
复制代码
还有一个相关的
  1. console.countReset()
复制代码
,可以使用它重置计数器。
console.trace()
  1. trace()
复制代码
在简单的数据中很难演示。当您试图在类或库中找出是哪个实际调用者导致了这个问题时,它的优势就显现出来了。
例如,可能有 12 个不同的组件调用一个服务,但是其中一个组件没有正确地设置依赖项。
  1. export default class CupcakeService {
复制代码
  1.    
复制代码
  1. constructor(dataLib) {
复制代码
  1. this.dataLib = dataLib;
复制代码
  1. if(typeof dataLib !== 'object') {
复制代码
  1. console.log(dataLib);
复制代码
  1. console.trace();
复制代码
  1.     }
复制代码
  1.   }
复制代码
  1.   ...
复制代码
  1. }
复制代码
这里使用
  1. console.log()
复制代码
仅告诉我们传递数据
  1. dataLib
复制代码
是什么 ,而没有具体的传递的路径。不过,
  1. console.trace()
复制代码
会非常清楚地告诉我们问题出在
  1. Dashboard.js
复制代码
,我们可以看到是
  1. new CupcakeService(false)
复制代码
导致错误。
console.time()
  1. console.time()
复制代码
是一个用于跟踪操作时间的专用函数,它是跟踪 JavaScript执行时间的好方法。
  1. function slowFunction(number) {
复制代码
  1. var functionTimerStart = new Date().getTime();
复制代码
  1. // something slow or complex with the numbers.
复制代码
  1. // Factorials, or whatever.
复制代码
  1. var functionTime = new Date().getTime() - functionTimerStart;
复制代码
  1. console.log(`Function time: ${ functionTime }`);
复制代码
  1. }
复制代码
  1. var start = new Date().getTime();
复制代码
  1. [/code][code]for (i = 0; i < 100000; ++i) {
复制代码
  1.   slowFunction(i);
复制代码
  1. }
复制代码
  1. [/code][code]var time = new Date().getTime() - start;
复制代码
  1. console.log(`Execution time: ${ time }`);
复制代码
  1. [/code]这是一种老派的做法,我们使用 [code]console.time()
复制代码
来简化以上代码。
  1. const slowFunction = number =>  {
复制代码
  1. console.time('slowFunction');
复制代码
  1. // something slow or complex with the numbers.
复制代码
  1. // Factorials, or whatever.
复制代码
  1. console.timeEnd('slowFunction');
复制代码
  1. }
复制代码
  1. console.time();
复制代码
  1. [/code][code]for (i = 0; i < 100000; ++i) {
复制代码
  1.   slowFunction(i);
复制代码
  1. }
复制代码
  1. console.timeEnd();
复制代码
我们现在不再需要做任何计算或设置临时变量。
console.group()


  1. // this is the global scope
复制代码
  1. let number = 1;
复制代码
  1. console.group('OutsideLoop');
复制代码
  1. console.log(number);
复制代码
  1. console.group('Loop');
复制代码
  1. for (let i = 0; i < 5; i++) {
复制代码
  1. number = i + number;
复制代码
  1. console.log(number);
复制代码
  1. }
复制代码
  1. console.groupEnd();
复制代码
  1. console.log(number);
复制代码
  1. console.groupEnd();
复制代码
  1. console.log('All done now');
复制代码
  1. [/code]输出如下:
  2. [img]https://201903.oss-cn-hangzhou.aliyuncs.com/wc/1811847-3aa2b06575e9f8006901afaa0952fa48[/img]
  3. 并不是很有用,但是您可以看到其中一些是如何组合的。
  4. [list][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][/list][code]class MyClass {
复制代码
  1. constructor(dataAccess) {
复制代码
  1. console.group('Constructor');
复制代码
  1. console.log('Constructor executed');
复制代码
  1. console.assert(typeof dataAccess === 'object',
复制代码
  1. 'Potentially incorrect dataAccess object');
复制代码
  1. this.initializeEvents();
复制代码
  1. console.groupEnd();
复制代码
  1.   }
复制代码
  1.   initializeEvents() {
复制代码
  1. console.group('events');
复制代码
  1. console.log('Initialising events');
复制代码
  1. console.groupEnd();
复制代码
  1.   }
复制代码
  1. }
复制代码
  1. let myClass = new MyClass(false);
复制代码
  1. [/code][code]
复制代码


这是很多工作和很多调试信息的代码,可能不是那么有用。 但它仍然是一个有趣的想法,这样写使你的日志记录更加清晰。
选择DOM元素
如果熟悉jQuery,就会知道
  1. $(‘.class’)
复制代码
  1. $(‘#id’)
复制代码
选择器有多么重要。它们根据与之关联的类或 ID 选择 DOM 元素。
但是当你没有引用 jQuery时,你仍然可以在谷歌开发控制台中进行同样的操作。
$(‘tagName’) $(‘.class’) $(‘#id’) and $(‘.class #id’) 等效于
  1. document.querySelector(‘ ‘)
复制代码
,这将返回 DOM 中与选择器匹配的第一个元素。
可以使用
  1. \$\$(tagName)
复制代码
  1. \$\$(.class)
复制代码
, 注意双元符号,根据特定的选择器选择DOM的所有元素。这也将它们放入数组中,你也可以通过指定数组中该元素的位置来从中选择特定的元素。
例如,&dollar;&dollar;(‘.className’) 获取具有类
  1. className
复制代码
的所有元素,而
  1. \$\$(‘.className’)[0]
复制代码
  1. \$\$(‘.className’)[1]
复制代码
获取到分别是第一个和第二个元素。

将浏览器转换为编辑器
你有多少次想知道你是否可以在浏览器中编辑一些文本? 答案是肯定的,你可以将浏览器转换为文本编辑器。 你可以在 DOM 中的任何位置添加文本和从中删除文本。
你不再需要检查元素并编辑HTML。相反,进入开发人员控制台并输入以下内容:
  1. document.body.contentEditable=true
复制代码
这将使内容可编辑。现在,你几乎可以编辑DOM中的任何内容。
查找与DOM中的元素关联的事件
调试时,需要查找 DOM 中某个元素的事件侦听器感时,谷歌控制台了
  1. getEventListeners
复制代码
使找到这些事件更加容易且直观。
  1. getEventListeners($(‘selector’))
复制代码
返回一个对象数组,其中包含绑定到该元素的所有事件。你可以展开对象来查看事件:


要找到特定事件的侦听器,可以这样做:
  1. getEventListeners($(‘selector’)).eventName[0].listener
复制代码
这将显示与特定事件关联的侦听器。这里
  1. eventName[0]
复制代码
是一个数组,它列出了特定事件的所有事件。例如:
  1. getEventListeners($(‘firstName’)).click[0].listener
复制代码
  1. [/code]将显示与 ID 为 [code]‘firstName’
复制代码
的元素的单击事件关联的侦听器。
监控事件
如果希望在执行绑定到 DOM 中特定元素的事件时监视它们,也可以在控制台中这样做。你可以使用不同的命令来监控其中的一些或所有事件:
如果希望在执行绑定到DOM中特定元素的事件时监视它们,也可以在控制台中这样做。你可以使用不同的命令来监控其中的一些或所有事件:
    1. monitorEvents($(‘selector’))
    复制代码
    将监视与选择器的元素关联的所有事件,然后在它们被触发时将它们打印到控制台。例如,
    1. monitore($(#firstName))
    复制代码
    将打印 ID 为
    1. firstName
    复制代码
    元素的所有事件。
    1. monitorEvents($(‘selector’),’eventName’)
    复制代码
    将打印与元素绑定的特定事件。 你可以将事件名称作为参数传递给函数。 这将仅记录绑定到特定元素的特定事件。 例如,monitorEvents($(‘#firstName’),’click’) 将打印绑定到ID为'firstName'的元素的所有
    1. click
    复制代码
    事件。
    1. monitore($(selector),[eventName1, eventName3', .])
    复制代码
    将根据您自己的需求记录多个事件。与其传递单个事件名作为参数,不如传递包含所有事件的字符串数组。例如
    1. monitore($(#firstName),[click, focus])
    复制代码
    将记录与ID firstName元素绑定的
    1. click
    复制代码
    事件和
    1. focus
    复制代码
    事件。
    1. unmonitorevent ($(selector))
    复制代码
    :这将停止监视和打印控制台中的事件。

检查 DOM 中的一个元素
你可以直接从控制台检查一个元素:
  • inspect($(‘selector’)) 将检查与选择器匹配的元素,并转到 Chrome Developer Tools中的 Elements 选项卡。 例如,
    1. inspect($(‘#firstName’))
    复制代码
    将检查 ID为'firstName' 的元素,
    1. spect($(‘a’)[3])
    复制代码
    将检查 DOM 中的第 4 个
    1. a
    复制代码
    元素。
  • $0, $1, $2 等可以帮助你获取最近检查过的元素。 例如,
    1. $0
    复制代码
    表示最后检查的 DOM 元素,而
    1. $1
    复制代码
    倒数第二个检查的 DOM 元素。

检索最后一个结果的值
你可以将控制台用作计算器。当你这样做的时候,你可能需要用第二个来跟踪一个计算。以下是如何从内存中检索先前计算的结果:
  1. $_
复制代码
过程如下:
  1. 2+3+4
复制代码
  1. 9 //- The Answer of the SUM is 9
复制代码
  1. [/code][code]$_
复制代码
  1. 9 // Gives the last Result
复制代码
  1. [/code][code]$_ * $_
复制代码
  1. 81  // As the last Result was 9
复制代码
  1. [/code][code]Math.sqrt($_)
复制代码
  1. 9 // As the last Result was 81
复制代码
  1. [/code][code]$_
复制代码
  1. 9 // As the Last Result is 9
复制代码
[h1]清除控制台和内存[/h1]如果你想清除控制台及其内存,输入如下:
  1. clear()
复制代码
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。



推荐阅读
(点击标题可跳转阅读)
10 个技巧,让你更专业地使用 console 进行 JS 调试
Javascript 调试命令——你只会 Console.log() ?
九个Console命令,让 JS 调试更简单




觉得本文对你有帮助?请分享给更多人
关注「前端大全」加星标,提升前端技能

喜欢就点一下「在看」呗~
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:195
帖子:39
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP