180

14招搞定JavaScript调试 | Fundebug博客

 6 years ago
source link: https://blog.fundebug.com/2017/11/08/14-javascript-debugging-tips/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

输出样式:

console_table_object.png

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

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

view_port.png

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

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

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

retrieve_dom_ele.png

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");
timer.png

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,输出结果如下:

strack_trace.png

我们可以清晰地看到func1调用func2func2调用func4func4创建了一个Car的实例,然后调用了car.funcX,等等。

有时候,尽管你认为对自己的代码非常清楚,使用console.trace依然可以帮你快速定位函数。比如,你想要改进代码,那么通过 trace 可以获取到所有相关的函数,而且每一个都可以点击直接跳转,就像一个快捷菜单一样。

广告: 如果你需要监控线上 JavaScript 代码的错误的话,欢迎免费使用Fundebug!

7. 将 minify 的代码还原

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

unminify_js.png

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

debug_f_name_console.png

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

输出的结果如下:

colorful_log.png

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

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

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

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

使用monitor函数可以获取到函数运行时传入的参数值。但是,有一个不足在于并没有指明该函数的形参个数。所以func1实际上是需要三个参数的,但是只传入了两个。如果忽略了这种情况,那么可能会导致 bug 出现。

12 在控制台快速访问元素

在控制台使用查询选择器(querySelector)很方便, 使用$('css-selector')就可以返回第一个匹配的元素,$$('css-selector')会返回所有匹配的元素。如果你会多次使用某个元素,甚至可以将其保存到变量中。

query_selector.png

13 Postman 很好(但是 Firefox 更快)

很多开发者使用 Postman 来发送 Ajax 请求。Postman 非常好用,但是打开一个新的窗口,并且配置请求对象还是有点繁琐。

如果你不需要担心使用 cookie 认证,那么你可以在 Firefox 中编辑和重发请求。

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

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

firefox_edit_resend.png

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

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

break_on_node_change.png

关于Fundebug

Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了70亿+错误事件,付费客户有阳光保险、达令家、核桃编程、荔枝FM、微脉等众多品牌企业。欢迎大家免费试用

您的用户遇到BUG了吗?

体验Demo 免费使用

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK