14招搞定JavaScript调试
14招搞定JavaScript调试
译者按: 很多时候,大家可能只是依靠console.log来调试JavaScript代码,这样做的局限性不言而喻,这篇博客将教你几招实用的调试技巧。
为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。
掌握工具的使用方法可以极大提高解决问题的效率。尽管JavaScript以难以Debug著称,如果你知道一些技巧可以让你更快地搞定它。本文我总结了14个Debug小技巧,也许会对你有用!
大多数技巧都是针对Chrome检查器(Inspector)和Firefox,尽管有很多人使用其他检查器。
1. debugger;
除了console.log
之外,debugger;
是我最喜欢的快速debug的工具。一旦在代码中加入了这行语句,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);
|
输出样式:
3. 尝试适配各种机型屏幕大小
如果你拥有各种型号的手机那么测试会相对简单,但是现实可不会这样。其实,你可以直接在浏览器你们改变viewport的大小来查看效果。谷歌浏览器提供了非常强大的功能。在谷歌开发者面板,点击toogle device mode
按钮,就可以选择不同的设备大小了。
4. 如何快速找到对应的DOM元素
构造一个DOM元素,然后在控制台(Console)下面使用。谷歌浏览器调试器(Chrome Inspector)保留了最后5个DOM元素的历史。最后一个标记为$0,倒数第二个$1, 以此类推。
如果你按照item-4
,item-3
,item-2
,item-1
,item-0
的顺序点击这些元素,那么你可以在控制台下使用$x
来访问它们。
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调用func2,func2调用func4,func4
创建了一个Car
的实例,然后调用了car.funcX,等等。
有时候,尽管你认为对自己的代码非常清楚,使用console.trace
依然可以帮你快速定位函数。比如,你想要改进代码,那么通过trace可以获取到所有相关的函数,而且每一个都可以点击直接跳转,就像一个快捷菜单一样。
广告: 如果你需要监控线上JavaScript代码的错误的话,欢迎免费使用Fundebug!
7. 将minify的代码还原
有时候,生产环境的代码出现问题,然而source map并没有和压缩的代码绑定在一起,所有无法看到还原的代码。不用担心,谷歌浏览器可以将JavaScript代码还原到一个可读的样式。尽管还是比不上真实的代码,但是可以很好的帮助你去分析问题了。点击{}
来结构化代码:
8. 快速定位需要Debug的函数
设想我们想要在函数中设置一个断点,最常见的两种方式是:
- 在检查器中找到这一行代码,然后设置断点;
- 在代码中添加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.log
,console.debug
,console.warn
,console.info
和console.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。
版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/11/08/14-javascript-debugging-tips/
您的用户遇到BUG了吗?
14招搞定JavaScript调试的更多相关文章
- 轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配 )
变量: 存储数据的容器 1.声明 var 2.作用域 全局变量. 局部变量. 闭包(相对的全局变量): 3.类型 a.基本类型(undefi ...
- 【】五句话搞定JavaScript作用域
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- 五句话搞定JavaScript作用域【转】
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- 30秒搞定javascript作用域
引用一下js权威指南的一名话作为开场”JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里.” javascript不存在大括号级的作用域,但他有函数作用域,也就是说变量 ...
- 五句话搞定JavaScript作用域
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- 两行代码搞定 JavaScript 的日期验证
我们通常在 JavaScript 中验证日期,基本的思路大概是,先判断年月日是否有效,再判断当月是否有当日,比如一些月份没有 31 日,平年二月没有 29.30 日,闰年二月没有 30 日等等. 偶然 ...
- 轻松搞定javascript预解析机制(搞定后,一切有关变态面试题都是浮云~~)
hey,guys!我们一起总结一下JS预解析吧! 首先,我们得搞清楚JS预解析和JS逐行执行的关系.其实它们两并不冲突,一个例子轻松理解它们的关系: 你去酒店吃饭,吃饭前你得看下菜谱,点下菜(JS预解 ...
- 五句话搞定JavaScript作用域(ES5)
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- 一招搞定多Offer选择
12月9号在论坛看到一位毕业生问了一个问题: 如今两个offer 一个在南京,搞.net ,公司是国电南自.税前一年加起来几乎相同7.2万.一个是在上海.搞java,公司名叫鑫合汇(不知道各位有没实用 ...
随机推荐
- python 将中文转拼音后填充到url做参数并写入excel
闲着没事写了个小工具,将中文转拼音后填充到url做参数并写如excel 一.先看下演示,是个什么东西 二.代码 代码用到一个中文转拼音的库,库是网上下的,稍微做了下修改,已经找不原来下载的地址了,然后 ...
- HDU_1394_Minimum Inversion Number_线段树求逆序数
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- Ubuntu 18.04 如何固定图标到任务栏
参考 https://blog.csdn.net/u014160286/article/details/81631863
- 用 foreach()循环三维数组
<?php $data = array( 0 => array( '中国' => 'china', '美国' => 'usa', '德国' => ' Germany', ...
- LINUX-查看进程内环境变量
ps -ef find PID cat /proc/$PID/environ | grep ENV
- JavaScript day3(数据类型)
数据类型(data type) JavaScript提供七种不同的数据类型(data types),它们是string(字符串), symbol(符号), number(数字), undefined( ...
- POJ1161——The Suspects
POJ1161——The Suspects The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 48 ...
- Python os.listdir() 方法
概述 os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表.这个列表以字母顺序. 它不包括 '.' 和'..' 即使它在文件夹中. 只支持在 Unix, Windows 下 ...
- 腾讯云:ubuntu搭建 FTP 文件服务
搭建 FTP 文件服务 安装并启动 FTP 服务 任务时间:5min ~ 10min 安装 VSFTPD 使用 apt-get 安装 vsftpd: sudo apt-get install vsft ...
- KD树学习小结
几个月后的UPD: 学习完下面之后,实战中的总结: 0.比赛中正解就是kdtree的题目很少很少 1.几类优先考虑kdtree的题目: k(维度) >= 3 的题目 二维平面上涉及区间标记的题目 ...