更快更高效地调试你的 JavaScript

了解你的工具在完成任务时有很重要的意义。 尽管 JavaScript 是出了名的难以调试,但是如果你掌握了一些小技巧,错误和 bug 解决起来就会快多了。

我们收集了 14 个你必须要知道的调试技巧,希望你可以牢记以便下次你需要它们来帮助你调试你的 JavaScript 代码。

让我们开始吧

大多数技巧都是用于 Chrome Inspector 和 Firefox,尽管有些可能也适用于其他调试器。

1. "debugger;"

除了 console.log, “debugger;” 是我最喜欢的临时应急调试工具。一旦它在你的代码中出现,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. 尝试所有的尺寸

拥有所有的移动设备这个想法是很美妙的,但是现实中是不可能的。不如取而代之,改变视口吧?Chrome 提供了所有你需要的东西。打开你的调试器并点击 "toggle device mode" 按钮。你会看到媒体查询出现啦!

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

在 elements 面板中标记一个 DOM 元素,然后在 console 中使用它。Chrome Inspector 会保存最后 5 个元素在其历史记录中,所以最后标记的元素可以用 $0 来显示,倒数第二个被标记的元素为 $1 ,以此类推。

如果你以 “item-4”, “item-3”, “item-2”, “item-1”, “item-0” 的顺序标记下面的这些元素,你可以像下图所示那样在 console 中访问这些 DOM 节点

5. 使用 console.time() 和 console.timeEnd() 对循环做基准测试

知道程序运行的确切时间是非常有用的,尤其当调试非常慢的循环时。通过给函数传参,你甚至可以启动多个计时器。让我们看看如何做:

console.time('Timer1');

var items = [];

for(var i = 0; i < 100000; i++){
  items.push({index: i});
}

console.timeEnd('Timer1');

得到如下输出:

6. 获取函数的堆栈踪迹

您可能了解 JavaScript 框架,生成大量代码 -- 快速地。

它会构建视图和触发事件,因此你最终会想要知道是什么在调用函数。

JavaScript 不是一个非常结构化的语言,所以有时很难搞清楚 发生了什么 和 什么时候发生的 。因此 console.trace (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();
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 调用了 func2 , 它又调用了func4。 func4 接着创建了一个 Car 的实例并调用了 car.funcX,等等。

即便你认为对你的代码很熟悉,这也仍然非常有用。假设你想优化你的代码。获取到函数堆栈踪迹以及所有相关的其他函数,每一个函数都是可点击的,你可以在他们之间来回跳转,就像一个菜单一样。

7. 解压缩代码以便更好地调试 JavaScript

有时生产环境会出现问题,而服务器无法提供 source map 。 不要害怕。 Chrome 可以解压你的 JavaScript 代码以更加可读的格式呈现。尽管格式化后的代码不可能跟源码一样有用,但至少你可以知道发生了什么。点击调试器 source 面板下面的 {} Pretty Print 按钮。

8. 快速定位要调试的函数

假设你想在某个函数中设置一个断点。

最常用的两种方式是:

  • 在调试器中找到相应的行并设置一个断点

  • 在你的脚本中添加一个 debugger

以上两种方法,你都必须到你的文件中找到你想调试的那一行。

可能不常见的方式是使用 console。在 console 中使用 debug(funcName),脚本会在运行到你传入的函数的时候停止。

这种方式比较快,缺点是对私有和匿名函数无效。但是,如果排除这些情形的话,这可能是定位要调试函数的最快方法。

var func1 = function() {
func2();
};

var Car = function() {
this.funcX = function() {
this.funcY();
}

this.funcY = function() {
this.funcZ();
}
}

var car = new Car();

在 console 中输入 debug(car.funcY),在调试模式下当调用 car.faunY 时脚本会停下来:

9. 不相关的黑盒脚本

我们经常会在我们的网页应用中用到一些库和框架。他们中大部分都经过良好的测试且相对来说错误较少。但是,调试器在执行调试任务时还是会进入这些不相关的文件。一个解决办法是将你不需要调试的脚本设置成黑盒。也包括你自己的脚本。更多关于调试黑盒的信息请参考这篇文章

10. 在复杂的调试中找到重要的信息

在更复杂的调试中我们有时想输出很多行。为了使你的输出保持更好的结构,你可以使用更多的 console 方法,如:console.log, console.debug, console.warn, console.info, console.error 等。然后,你还可以在调试器中过滤他们。但是有时当你调试 JavaScript 时,这并不是你真正想要的。现在,你可以给你的信息添加点创意和样式了。你可以使用 CSS 并制定你自己的 console 输出格式:

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 表示一个字符串,%i 表示整型,%c 表示自定义样式。你可能会找到更好的方式来使用它们。如果你使用单页面框架,你可能想对 view 的输出信息使用一种样式,对 models,collections,controllers 等使用其他的样式,你可能会使用 wlog,clog,mlog 等简称来命名。总之,尽情发挥你的创造力吧。

11. 监控一个特定的函数调用及其参数

在 Chrome 的 console 面板中,你可以监视一个特定的函数。每次该函数被调用,它将连同传入的参数一起打印出来。

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

将输出:

这是一个查看函数所传入参数的好办法。但是我认为如果 console 能够告诉我函数需要传入的参数个数的话会更好。上面的例子中,func1 需要传入 3 个参数,但是只传了 2 个参数。如果代码中没有对这种情况进行处理,可能会导致 bug。

12. 在 console 中快速查询元素

在 console 中执行 querySelector 的一个更快的办法是使用 $ 符号。$('css-selector') 会返回 CSS 选择器所匹配的第一个元素。$$(‘css-selector’) 会返回所有的元素。如果你要不止一次地使用该元素,最好是把它作为变量缓存起来。

13. Postman 是个好东西(但 Firefox 更快)

很多开发者在使用 Postman 来处理 ajax 请求。Postman 很优秀,使用它需要打开一个新的浏览器窗口,然后编写请求体然后测试,有点烦人。

有时使用你的浏览器会更轻松。

使用浏览器,当你向一个基于密码保护的网页发送请求时你不用再担心 cookie 的认证。你可以在 Firefox 中编辑并再次发送请求。

打开调试器并跳转到 network 选项。右键点击你想要修改的请求并选择 Edit and Resend,你就可以修改任何你想要修改的东西了。你可以修改头部以及参数然后点击 resend。

下面我提交了两个参数不同的请求:

14. 打断节点的变化

DOM 是个有趣的东西。有时它发生了变化,然而你却一脸懵逼,不知道为啥。但是,当你使用 Chrome 调试 JavaScript,DOM 发生变化时,你可以暂停,甚至可以监控属性的变化。在 Chrome Inspector 中,右键点击某个元素,然后选择 break on 设置来使用:

最后,为你推荐:

【第1099期】Eruda: 手机网页调试利器

【第571期】基于Postman的API自动化测试

【第556期】一探前端开发中的JS调试技巧

关于本文

转自:微信公众号:前端早读课

译者:@ParadeTo(掘金翻译计划)
校对者:@Yuuoniy, @lampui
作者:@Luis Alonzo
原文:https://raygun.com/javascript-debugging-tips
译文:https://github.com/xitu/gold-miner/blob/master/TODO/javascript-debugging-tips.md

js_调试_01_14 个你可能不知道的 JavaScript 调试技巧的更多相关文章

  1. 【转载】14个你可能不知道的 JavaScript 调试技巧

    了解你的工具可以极大的帮助你完成任务.尽管 JavaScript 的调试非常麻烦,但在掌握了技巧 (tricks) 的情况下,你依然可以用尽量少的的时间解决这些错误 (errors) 和问题 (bug ...

  2. 14 个你可能不知道的 JavaScript 调试技巧

    了解你的工具可以极大的帮助你完成任务.尽管 JavaScript 的调试非常麻烦,但在掌握了技巧 (tricks) 的情况下,你依然可以用尽量少的的时间解决这些错误 (errors) 和问题 (bug ...

  3. 14个你可能不知道的JavaScript调试技巧

    调试JS的时候,搜索一下这个标题

  4. 10个你可能不知道的JavaScript小技巧

    1.变量转换 看起来很简单,但据我所看到的,使用构造函数,像Array()或者Number()来进行变量转换是常用的做法.始终使用原始数据类型(有时也称为字面量)来转换变量,这种没有任何额外的影响的做 ...

  5. js值----你所不知道的JavaScript系列(6)

    1.数组 在 JavaScript 中,数组可以容纳任何类型的值,可以是字符串.数字.对象(object),甚至是其他数组(多维数组就是通过这种方式来实现的) .----<你所不知道的JavaS ...

  6. 你所不知道的 CSS 滤镜技巧与细节

    承接上一篇你所不知道的 CSS 动画技巧与细节,本文主要介绍 CSS 滤镜的不常用用法,希望能给读者带来一些干货! OK,下面直接进入正文.本文所描述的滤镜,指的是 CSS3 出来后的滤镜,不是 IE ...

  7. 你所不知道的 CSS 阴影技巧与细节

    关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow 的用法. 最近一个新的项目,CSS-Ins ...

  8. js类型----你所不知道的JavaScript系列(5)

    ECMAScirpt 变量有两种不同的数据类型:基本类型,引用类型.也有其他的叫法,比如原始类型和对象类型等. 1.内置类型 JavaScript 有七种内置类型: • 空值(null) • 未定义( ...

  9. 闭包----你所不知道的JavaScript系列(4)

    一.闭包是什么? · 闭包就是可以使得函数外部的对象能够获取函数内部的信息. · 闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. · 闭包就 ...

随机推荐

  1. Spring使用Cache、整合Ehcache(转)

    Spring使用Cache 从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我 ...

  2. VueJS组件通过props自定义事件

    父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件! 我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events inter ...

  3. 【Union Find】JAVA implementation

    import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Scan ...

  4. ubuntu16.04下Cmake学习一

    根据网上的资料,我总结了一下,一个工程应该有根目录(bin)存放可执行文件,头文件目录(include)存放头文件,源码文件(src)存放你的算法,还需要一个库文件夹存放你编译的静态库或者动态库.然后 ...

  5. 分布式搜索elasticsearch 环境搭建

    1.elasticsearch安装 elasticsearch的安装超级easy,解压即用(要事先安装好java环境). 到官网 http://www.elasticsearch.org下载最新版的 ...

  6. 自制小工具大大加速MySQL SQL语句优化(附源码)

    引言 优化SQL,是DBA常见的工作之一.如何高效.快速地优化一条语句,是每个DBA经常要面对的一个问题.在日常的优化工作中,我发现有很多操作是在优化过程中必不可少的步骤.然而这些步骤重复性的执行,又 ...

  7. 解决ListView滑动时出现黑边的问题

    [声明]转载请注明出处,此文出自指尖飞落的博客:http://blog.csdn.net/huntersnail --尊重作者,知识无价.交流无限! 两种方法 1.代码去边缘线 myList.setF ...

  8. CentOS 配置网络

    1.编辑ifcfg-eth0 vi /etc/sysconfig/network-scripts/ifcfg-eth0 2.修改NOBOOT=yes 3.重启服务 service network re ...

  9. Maven中央仓库地址(实用版)

    最近做项目的时候,一直发现常用的oschina maven源一直都没有反应,后面发现原来oschina竟然关闭了maven源服务,后面经同事推荐了阿里云的maven源,这速度杠杠的 Maven 中央仓 ...

  10. C语言--循环结构

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenVveW91MTMxNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...