常言道:工欲善其事必先利其器。虽然 JavaScript 确实难以调试,但是如果你能多掌握一些调试相关的小技巧,那么在面对错误和 bug 的时候你将能更快的解决掉它们。
我们在这里列举了 14 个你可能还不知道,但确实行之有效的调试小技巧,希望你能在下次调试你的时候用到。
让我们开始吧!
这里提到的大多数技巧都是针对于 Chrome 和 Firefox 检查工具的,可能这些技巧在其他浏览器中也能使用。
-
debugger
debugger是除了console.log外,我最喜欢也最常用的调试工具。当debugger出现在里的代码中,Chrome 会在执行到这里的时候自动的停下来。你还可以把debugger放在条件语句中,这样就可以只在你需要停止的地方停止。if (thisThing) { debugger; } -
Display objects as a table(用 table 来展示对象数据)
有时你会想要在控制台下查看复杂对象组成的数组,你可以继续使用console.log打印出所有的数据,然后通过滚动滚动条来查看每一条数据,或者是时候给console.table一个机会了,它将会让数据更一目了然。var animals = [ { animal: 'Horse', name: 'Henry', age: 43 }, { animal: 'Dog', name: 'Fred', age: 13 }, { animal: 'Cat', name: 'Frodo', age: 18 }, ] console.table(animals);输出结果:
console.table
-
Try all the sizes(响应式布局)
如果你能拥有所有不同尺寸的移动设备会不会很酷,然而这在现实中却是不现实的(译者注:调试起来也是够麻烦的吧)。既然无法拥有所有尺寸的设备,那我们能不能通过修改视口(viewport)大小 来模拟任意尺寸的设备呢?很显然 Chrome 浏览器的开发人员也想到了这一点,点击调试工具的toggle device mode(切换设备模式)按钮打开新世界,看看你的响应式布局是不是写的贼溜。
media querys
-
How to find your DOM elements quickly(在控制台中快速选定你要的 DOM 元素)
在 Elements 面板中选中一个节点,你可以直接在 console 命令行中直接找到这个节点,而不需要再进行 dom 查找。Chrome 调试工具会自动的记录最近选中的 5 个 DOM 节点,在控制台下分别通过$0、$1、$2、$3、$4访问。对于下面的 DOM 结构,如果你依次选中
item-4、item-3、item-2、item-1、item-0,你可以通过$0-4快速的在 console 命令行中使用这些节点。
$
-
Benchmark loops using console.time() and console.timeEnd() (使用 console.time 来衡量执行耗时)
如果能够确切的知道一段代码执行花费了多长的时间,尤其是对于比较慢的循环,这对我们代码的调优将会很有用。使用console.time你甚至可以通过在调用console.time的时候传入 不同的 label(关键字)记录不同的代码运行所花的时间。console.time('Timer1'); var items = []; for(var i = 0; i < 100000; i++){ items.push({index: i}); } console.timeEnd('Timer1');上面的代码会输出以下内容:
console.time
-
Get the stack trace for a function(跟踪方法调用链)
在进行 JavaScript 相关开发的时候我们肯定会用到一些框架来构建我们的页面,处理相关事件。由于 JavaScript 是非结构化语言,有时候将很难知道在 什么时候 发生了 什么事情 。这个时候我们就可以使用console.trace来快速找到一个函数的调用链帮助我们调试了。举个例子,我们希望能够跟踪到第 33 行 car 实例的 funcZ 是通过怎样的调用链被调用的。
var car; var func1 = function() { func2(); } var func2 = function() { func4(); } var func3 = function() { } var func4 = function() { car = new Car(); car.funcX(); } var Car = function() { this.brand = 'volvo'; this.color = 'red'; this.funcX = function() { this.funcY(); } this.funcY = function() { this.funcZ(); } this.funcZ = function() { console.trace('trace car') } } func1();上面的代码输出如下:
console.trace
通过输出我们可以明确的看到 car.funcZ 是通过 func1 调用 func2, func2 调用 func4,在 func4 中新建 Car 的实例,然后调用 car.funcX,最后在 car.funcX 中调用 car.funxY,在 car.funcY 中调用 car.funcZ 这样一个调用链被触发的。
尽管你会觉得我的代码是我完全可控的,我很清楚函数都是如何调用的,但请相信
console.trace真的很好用。假设我们现在想要优化一下代码,你只需要在相应的方法里面添加上console.trace,然后就能明确的看到该方法是如何被触发的。等等,console.trace输出的结果还是可点击的,你可以通过点击直接跳转到对应的代码位置,所以除了展示调用链我们还多了个额外的目录。 -
Unminify code as an easy way to debug JavaScript(格式化压缩过后的 JavaScript 代码)
线上的代码通常都是压缩过的,而且 sourceMap 文件也不会在线上服务被使用,这可怎么调试线上代码呢?不要怕,有问题找工具,Chrome 可以对 JavaScript 代码进行格式化,将其变成可读的。虽然比不上源代码的可读性,但至少你能看出代码是如何运行的。要格式化一个 JavaScript 文件,只需要点击 Sources 面板下方的
{}按钮
pretty code
-
Quick-find a function to debug(快速开始方法的调试)
当我们想要调试一个方法的时候,最常用的添加断点的方法是:- 在 source 面板中找到对应方法所在行,添加一个断点
- 在代码中添加
debugger
不管采用上面那种方法设置断点,你都需要在代码中找到特定的行才能添加断点,这可能并不那么容易。
其实在
console命令行中使用debug(funcName)就能快速的添加对于对应函数的断点,一旦这个函数开始执行的时候就会像添加了debugger一样在这里暂停下来。这样会比前面两种方法更快的添加断点,要说有什么不好的就是使用这种方法对匿名函数不适用。只要不是匿名函数的情况,这将会是最快的开始一个方法调试的途径。
注意
console.debug和debug(funcName)并不是同一回事。var func1 = function() { func2(); } var Car = function () { this.funcX = function() { this.funcY(); } this.funcY = function() { this.funcZ(); } } var car = new Car();在控制台下输入
debug(car.funcY),在控制台打开的情况下如果脚本运行到car.funcY这个方法的时候就会暂停下来。
debug
-
Black box scripts that NOT relevant(跳过不相关代码的断点)
日常开发中我们经常会使用到很多第三方的Js库,这些 Js 库文件都是经过很好的测试过的,通常可以认为这些代码是没有 bug 的,按说应该可以跳过调试断点的。但是实际上浏览器并不区分这些代码,代码运行时如果这些代码里面存在断点,断点依然会在这里暂停下来,这会打断我们的调试工作。解决方案就是把这些不需要调试的代码(包括你自己的代码)添加到 black box 里面,跳过里面的所有断点。更多相关内容请查看这里 -
Find the important things in complex debugging(快速抓住重点)
在一些复杂的场景下我们可能会在控制台下输出很多的内容,良好的输出格式帮助我们更好的找到关键点。做到这一点我们可以使用console.log,console.debug,console.debug,console.warn,console.info和console.error等方法输出不同格式的日志,然后通过筛选器就能过滤出我们所关心的日志内容。但有时候这并不是你所想要的调试方法,这样的输出并不突出,为了更好的突出重点内容,你可以在控制台下使用 CSS 来装饰你的输出内容,这会更好的突出内容,帮助你快速抓住重点。console.todo = function(msg) { console.log('%c%s%s%s', 'color: yellow; background-color: black', '-', msg, '-'); } console.important = function(msg) { console.log('%c%s%s%s', 'color: brown; font-weight: bold; text-decoration: underline;', '-', msg, '-'); console.todo('This is something that\'s need to be fixed'); console.important('This is an important message'); }输出内容如下:
console
在使用console.log的时候,我们可以使用%s来作为字符串的占位符,%i作为数字的占位符,还可以使用%c来使用自定义样式。你可以以任意你能想象到的样式来使用它们,比如在调试一个单页应用的时候,我们可以对于不同模型的日志(model, controller)输出为不同的样式,方便快速定位不同模块的日志输出。除此之外你还可以为这些方法定义更简短的方法名,方便调用。 -
Watch specific function calls and its arguments
在 Chrome 的控制台下,我们可以完全地监听特定方法的调用,一旦添加了特定方法的监听,每当这个方法被调用的时候都会在控制台下打印出调用时传入的参数。var func1 = function(x, y, z) { // ... } monitor(func1); func1(1, 2);
monitor
-
Quickly access elements in the console(快速在控制台下选择元素)
在控制台下我们可以方便的使用$('css-selector')符来实现
querySelector的功能,使用$$('css-selector')来实现querySelectorAll的功能。如果你需要多次访问同一个 DOM 元素,将这个元素保存到一个变量里面是很实用的。
$$
-
Postman is great(but Firefox is faster)
很多开发者都会使用 Postman 工具来调试 ajax 相关内容。虽然 Postman 确实很好用,但是强迫症表示要重开一个浏览器窗口然后手动新建一个请求才能测试有点不能接受。
比起使用 Postman 工具,有时候你的浏览器在处理 ajax 相关内容的时候会更快。
当你使用浏览器默认的网络面板来进行 ajax 调试的时候,还能保留用户的登录信息不需要再手动去请求里面添加 cookie 等信息,在 Firefox 下你甚至可以对一些请求直接进行编辑然后重发。
如何来实现呢?只需要打开开发工具,切换到 network 面板,找到你想要编辑的请求记录,右击选择Edit and Resend然后就可以随意的修改添加任何你想要的参数了,点击resend就能按照你修改后的请求发送了。
image.png
-
Break on node change(在DOM节点变化的时候break)
DOM 操作是一件有趣的事,但是对于调试而言有时看到 DOM 发生的变化,但是我们并不知道变化是如何发生的,这就非常难调试了。好在 Chrome 给我们提供了 DOM 变化时的debugger工具(译者注:暂停的效果和 JavaScript debugger 类似)。开启一个 DOM 的变化监听,只需要在 Element 面板中选择一个 DOM元素 然后右键在最下面的Break on菜单的子目录下选择一种断点方式就可以了。
Break on node change
可选的断点方式:子节点变化,自身属性变化,移除node。












网友评论