大家都知道熟悉掌握工具的使用能让我们事倍功倍,对完成任务的产生的影响非常大。对于JavaScript的调试,都一直说是难以调试,但事实上如果你掌握一些调试技巧,那么解决一些问题或调试Bug的时间会少很多。
这篇文章整理了14个你可能不知道的调试技巧,但是下次你发现自己需要调试的JavaScript代码时,可能会用得上,也会因此记住这些调试技巧。
这些调试技巧大部分都是针对Chrome和Firefox的浏览器,尽管也有许多和其他浏览器调试工具一样。接下来,我们开始了解这些调试技巧。
debugger
可以使用console.log
和debugger
来调试你的JavaScript,这也是我最喜欢的调试工具。一旦在你的代码中使用了debugger
调试代码,Chrome会自动停止执行的JavaScript代码。你甚至可以将它封装到条件语句中,只在需要时才运行。
if (thisThing) {
debugger;
}
对象表格显示
有时,你需要查看一个复杂的对象集,你可以在控制台上以一个表格的形式展示,这样让你更容易看到你片在处理的事情。
var animals = [
{ animal: 'Horse', name: 'Henry', age: 43 },
{ animal: 'Dog', name: 'Fred', age: 13 },
{ animal: 'Cat', name: 'Frodo', age: 18 }
];
console.table(animals);
输出的结果:
尝试所有尺寸
虽然你桌上的每一个移动设备都很棒,但在现实世界里是不可行的。那么Chrome提供了你所需要的一切,可以调整你的viewport
。进入“检查器”(Inspector),点击“切换设备模式”。可以查看媒体查询的效果。
如何快速找到DOM元素
在元素面板中标记一个DOM元素,并在控制台中使用它。Chrome检查器保留了它历史上的最后五个元素,$0
表示第一个元素,$1
表示第二个元素,以此类推。
如果你的模板中有item-4
、item-3
、item-2
、item-1
和item-0
几个标签,然后你可以在控制台上这样访问DOM节点:
使用console.time()
和console.timeEnd()
在调试循环时,知道要执行多长时间是非常有用的。你甚至可以通过为方法分配一个标签来设置多个定时器。让我们来看看它是如何工作的:
console.time('Timer1');
var items = [];
for(var i = 0; i < 100000; i++){
items.push({index: i});
}
console.timeEnd('Timer1');
结果如下:
获取函数的堆栈跟踪
你可能知道JavaScript框架,快速生成大量代码。
它创建视图并触发事件,所以最终你将想知道是什么导致了函数调用。
由于JavaScript不是一种结构化的语言,所以有时候很难对所发生的事情和何时进行做出描述。使用console.trace
可以方便地调试JavaScript。
假设你希望在第33行实例中看到函数调用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();
第33行输出的结果:
现在我们可以看到func1
,它叫func4
。然后,func4
创建了Car
的实例,然后调用函数car.funcX
等。
即使你认为你很了解你的脚本,但这仍然很方便。比方说你想改进你的代码,获取所有相关函数的跟踪和列表,每一个都是可点击的,你现在可以在它们之间来回切换。它就像你的菜单。
调试压缩的JavaScript代码
有时你可以在生产中遇到问题,而你的源映射并没有完全发布到服务器。不要害怕。Chrome可以使你的JavaScript文件变得更容易阅读。代码不会像你的真实代码那样有用 —— 但至少你能看到发生了什么。单击检查器中的source
中的{}
按钮。
快速调试函数
假设你想在函数中设置断点。
最常见的两种方法是:
- 在检查器中找到一行并添加一个断点
- 在脚本中添加一个
debugger
在这两种解决方案中,都必须在文件中单击,才能找到想要调试的特定行。
更不常见的是使用控制台。在控制台中使用debug
(funcName
),当它到达你传入的函数时,脚本将停止。
它很快,但缺点是它不适用于私有或匿名函数。但如果不是这样的话,这可能是找到调试函数的最快方法。注意,这和console.debug
函数不是同一回事。
var func1 = function() {
func2();
};
var Car = function() {
this.funcX = function() {
this.funcY();
}
this.funcY = function() {
this.funcZ();
}
}
var car = new Car();
在控制台的类型调试中(car.funcY
),脚本在调用car.funcY
时将停止调试模式。
不相关的黑盒脚本
今天,我们经常在Web应用程序上使用一些库和框架。它们中的大多数都经过了很好的测试,相对来说不会有什么Bug。但是,调试器仍然会进入与此调试任务无关的所有文件。解决方案是将不需要调试的黑盒脚本。这也可以包括你自己的脚本。在本文中阅读更多关于调试黑盒的内容。
在复杂的调试中找到重要的事情
在更复杂的调试中,我们有时希望输出行多行。为了保持更好的输出结构,你可以做的一件事情是使用更多的控制台功能。例如console.log
、console.debug
、console.warn
、console.info
和console.error
等。然后你可以在你的检查器中过滤它们。但有时候,当需要调试JavaScript时,这并不是你想要的。现在,你可以对你的信息进行个性化的设计。当你想调试JavaScript时,使用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.log()
你可以通过%s
设置String
,%i
设置Integer
个性化样式。你可能会找到更好的方法来使用它。如果你使用一个单一的页面框架,你可能希望有一种样式来查看消息,另一种样式用于模型、集合、控制器等。也许还可以命名为wlog
、clog
和mlog
等你能想得出来的名字。
观察特定函数调用及其参数
在Chrome控制台中,你可以关注指定的函数。每次调用该函数时,它将记录传入的值。
var func1 = function(x, y, z) {
//....
};
输出的结果如下:
这是一种很好的方法,可以看到哪些参数传递到函数中。但我必须说,如果控制台能打印出函数的参数有多少,那就太好了。在上面的示例中,func1
有三个参数,但只有2
个被传入。如果在代码中没有做相应的处理,那么就会导致Bug的出现。
快速访问控制台中的元素
在控制台上执行比querySelector
的更快的方法是使用$
符号。$('css-selector')
将返回css-selector
选择器的第一个匹配项。$$('css-selector')
将返回所有的css-selector
。如果你不止一次使用一个元素,那么将它们作为一个变量保存是非常有用的。
Postman非常棒(但Firefox更快)
许多开发人员使用Postman来处理Ajax请求。Postman是非常优秀的,但是打开一个新的浏览器窗口,编写新的Ajax请求对象,然后测试它们会有点麻烦。
有时使用浏览器更容易些。
当你这样做的时候,你不需要担心身份验证,如果你发送到一个密码安全页面,也就不需要验证cookie
。这就是如何在Firefox中编辑和重新发送请求的方法。
打开检查器,转到network
标签。右键单击所需的请求并选择Edit
和Resend
。现在你可以改变任何你想要的东西。更改标题并编辑参数,然后点击Resend
。
以下是我提出的两次不同性质的请求:
打断节点变化
DOM可能是一件有趣的事情。有时候事情会改变,你也不知道为什么。但是,当需要调试JavaScript时,当DOM元素发生了变化时,Chrome允许你暂停。你甚至可以监视它的属笥。在Chrome浏览器的检查器中,右键单击该元素,并选择设置为打断:
本文根据@Luis Alonzo 的《The 14 JavaScript debugging tips you probably didn't know》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:https://raygun.com/javascript-debugging-tips。
如需转载,烦请注明出处:https://www.w3cplus.com/tools/javascript-debugging-tips.html