更快更高效地调试你的 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. CDH集群集成kafka

    搭建要求: 1.CDH环境已经搭建成功,在CDH上搭建kafka.要求用CDH上zookeeper管理kafka而不用kafka自带的zookeeper 2.kafka_2.11-0.8.2.1.tg ...

  2. 2、C++ 的升级

    1.内联函数     define 可以定义宏代码片段,但是,C++ 推荐使用内联函数替代宏代码片段. inline int f(int a, int b) { }     只需要在 函数定义(实现) ...

  3. Log4net日志记录、详细配置(自己使用>)

    log4net库是Apache log4j框架在Microsoft.NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台.文件.数据库等)的工具 1.首先添加对log4net.dll的引 ...

  4. Freebsd的ports命令

    安装 make clean 卸载 make deinstall 重装 make reinstall 清理 make clean 列出配置单 make config 恢复默认的配置单 make rmco ...

  5. EMC机理------串扰

    转:电子工程师不得不知道的EMC机理------串扰(韬略科技EMC) 串扰是信号完整性中最基本的现象之一,在板上走线密度很高时串扰的影响尤其严重.我们知道,线性无缘系统满足叠加定理,如果受害线上有信 ...

  6. msgsnd的一个小问题

    今天写了一个System V消息队列的小样例.定义了一个例如以下的结构体: #define MSG_SIZE 8192 struct request { long mtype; int client_ ...

  7. Jest — ElasticSearch Java 客户端

    1. 介绍 任何使用过Elasticsearch的人都知道,使用基于rest的搜索API构建查询可能是单调乏味且容易出错的. 在本教程中,我们将研究Jest,一个用于Elasticsearch的HTT ...

  8. Spark Streaming和Kafka整合开发指南(二)

    在本博客的<Spark Streaming和Kafka整合开发指南(一)>文章中介绍了如何使用基于Receiver的方法使用Spark Streaming从Kafka中接收数据.本文将介绍 ...

  9. nginx支持pathinfo模式

    很久不使用apache了,渐渐对apache感到陌生,因为朋友有个ZendFramework框架从apache移到nginx下,需要pathinfo模式支持.网上海搜于是开始搜索nginx+pathi ...

  10. 禁用android studio自身的ndk编译disable automatic ndk-build call

    1,让studio不自动编译jni文件,而是我们手动通过ndk-build编译    打开工程下面的app文件夹, 找到build.gradle   添加如下:  defaultConfig {   ...