14招搞定JavaScript调试

译者按: 不少时候,你们可能只是依靠console.log来调试JavaScript代码,这样作的局限性不言而喻,这篇博客将教你几招实用的调试技巧。javascript

为了保证可读性,本文采用意译而非直译。另外,本文版权归原做者全部,翻译仅用于学习。css

掌握工具的使用方法能够极大提升解决问题的效率。尽管JavaScript以难以Debug著称,若是你知道一些技巧可让你更快地搞定它。本文我总结了14个Debug小技巧,也许会对你有用!java

大多数技巧都是针对Chrome检查器(Inspector)和Firefox,尽管有不少人使用其余检查器。node

1. debugger;

除了console.log以外,debugger;是我最喜欢的快速debug的工具。一旦在代码中加入了这行语句,Chrome在执行的时候会自动在该行停下来。你甚至能够和条件语句配合使用,仅仅在你须要它的时候开启。chrome

if(thisThing){
debugger;
}

2. 将对象以表格的形式展现

有时候,你须要查看一个复杂的对象元素。一般,咱们都会使用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);

输出样式:cookie


3. 尝试适配各类机型屏幕大小

若是你拥有各类型号的手机那么测试会相对简单,可是现实可不会这样。其实,你能够直接在浏览器大家改变viewport的大小来查看效果。谷歌浏览器提供了很是强大的功能。在谷歌开发者面板,点击toogle device mode按钮,就能够选择不一样的设备大小了。网络


4. 如何快速找到对应的DOM元素

构造一个DOM元素,而后在控制台(Console)下面使用。谷歌浏览器调试器(Chrome Inspector)保留了最后5个DOM元素的历史。最后一个标记为$0,倒数第二个$1, 以此类推。框架

若是你按照item-4item-3item-2item-1item-0的顺序点击这些元素,那么你能够在控制台下使用$x来访问它们。dom


5. 使用console.time()和console.timeEnd()来记录时间

了解代码的执行时间是很是有用的,特别是调试耗时的for循环。你能够经过定义不一样的名字来设置多个timer。咱们来演示一下如何操做:

console.time('Timer1');
 
var items = [];
 
for(var i = 0; i < 100000; i++){
items.push({ index: i});
}
 
console.timeEnd('Timer1');

6. 获取某个函数的Stacktrace

你也许知道很多JavaScript框架,它们能够一键快速生成大量代码。代码里面包含各类view和事件触发器,最终你会想要搞明白某些函数是如何被调用的。

由于JavaScript并非一个很结构化的语言,全部有时候要搞清楚什么时候如何发生的仍是比较困难的。在这个时候,咱们可使用console.trace来debug JavaScript。

好比,若是你想看到一个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();
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,输出结果以下:


咱们能够清晰地看到func1调用func2func2调用func4func4建立了一个Car的实例,而后调用了car.funcX,等等。

有时候,尽管你认为对本身的代码很是清楚,使用console.trace依然能够帮你快速定位函数。好比,你想要改进代码,那么经过trace能够获取到全部相关的函数,并且每个均可以点击直接跳转,就像一个快捷菜单同样。

广告: 若是你须要监控线上JavaScript代码的错误的话,欢迎无偿使用Fundebug!

7. 将minify的代码还原

有时候,生产环境的代码出现问题,然而source map并无和压缩的代码绑定在一块儿,全部没法看到还原的代码。不用担忧,谷歌浏览器能够将JavaScript代码还原到一个可读的样式。尽管仍是比不上真实的代码,可是能够很好的帮助你去分析问题了。点击{}来结构化代码:


8. 快速定位须要Debug的函数

设想咱们想要在函数中设置一个断点,最多见的两种方式是:

  1. 在检查器中找到这一行代码,而后设置断点;
  2. 在代码中添加debugger

不管哪一种方法,你都须要在全部的代码文件中首先找到须要debug的那一行。

还有一个不经常使用的方式是使用控制台(console),使用debug(funcName),脚本会在那行函数处暂停。使用这个方法能够很快定位函数,可是对于私有和匿名函数不适用。(注意:debug和console.debug不是同一个事情!)

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模式。


9. 屏蔽不相关脚本

咱们的代码中都会引入很多库函数和框架。大多数都是通过测试,几乎没有什么bug的。可是debugger会一不当心跳进去。所以,咱们能够选择将这些脚本屏蔽。能够查看谷歌浏览器屏蔽文件的设置火狐浏览器屏蔽文件的设置

10. 个性化console.log信息

在一些很复杂的Debug中,咱们须要输出不少行的日志,使用Console.logconsole.debugconsole.warnconsole.infoconsole.error。你可使用过滤器来查看特定的消息,可是有时候你会发现这样并不够。咱们可使用更加富有创造力的方法,使用CSS来个性化定义Console.log打印的消息:

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

输出的结果以下:


你能够用%s来输出字符串,%i来输出数字,%c来自定义格式。若是你使用单页面框架,对于视图(view)的console消息使用一种格式,模型(model)、集合,控制器各自使用不一样的格式。甚至,你可能想要更短的名字,相似于wlog, clog和mlog。

11. 查看某个函数调用和其参数值

在谷歌浏览器控制台,你能够一直观察某个函数。每次它被调用,都会打印传入的参数值。

var func1 = function(x, y, z) {
//....
};

使用monitor函数能够获取到函数运行时传入的参数值。可是,有一个不足在于并无指明该函数的形参个数。因此func1其实是须要三个参数的,可是只传入了两个。若是忽略了这种状况,那么可能会致使bug出现。

12 在控制台快速访问元素

在控制台使用查询选择器(querySelector)很方便, 使用$('css-selector')就能够返回第一个匹配的元素,$$('css-selector')会返回全部匹配的元素。若是你会屡次使用某个元素,甚至能够将其保存到变量中。


13 Postman很好(可是Firefox更快)

不少开发者使用Postman来发送Ajax请求。Postman很是好用,可是打开一个新的窗口,而且配置请求对象仍是有点繁琐。

若是你不须要担忧使用cookie认证,那么你能够在Firefox中编辑和重发请求。

打开检查器,跳转到网络(network)标签。右键点击选中的请求,选择编辑和重发选项。

下图是我将同一个GET请求的属性编辑后再次发送出去的状况:


14 监控节点元素变化并中断

有时候DOM莫名其妙变化了,然而你并不知道为啥。好在谷歌浏览器提供了一个功能能够在DOM元素变化的时候暂停执行。在谷歌检查器下,右键选中的元素,而后选定要监控的变化类型:Subtree Modifications, Attributes Modifications, Node Removal。


相关文章
相关标签/搜索