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-4item-3item-2item-1item-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调用func2func2调用func4func4创建了一个Car的实例,然后调用了car.funcX,等等。

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

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

7. 将minify的代码还原

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

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

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

输出的结果如下:

你可以用%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了吗?

时间: 2024-10-23 14:45:19

14招搞定JavaScript调试的相关文章

轻松搞定javascript预解析机制(搞定后,一切有关变态面试题都是浮云~~)

hey,guys!我们一起总结一下JS预解析吧! 首先,我们得搞清楚JS预解析和JS逐行执行的关系.其实它们两并不冲突,一个例子轻松理解它们的关系: 你去酒店吃饭,吃饭前你得看下菜谱,点下菜(JS预解析),但吃的时候还是一口一口的吃(JS逐行执行)! OK,解决下面五个问题,JS预解析就算过了~~(前提:对JS变量作用域有清晰理解) 一.JS预解析是什么? 其实就是对程序要用到的材料(变量,函数)给一个初始值,并存到一个表中(我自己虚构的),当程序运行到那一行时,就来这个表看有没有初始值,没有就

轻松搞定javascript原型链 _proto_

//如有错误或不同观点,欢迎批评与讨论!首先,prototype出现的目的,是为了解决 代码重用 的问题 , prototype 相当于是在内存上划分出一个公共的区域, 专用于存放 实例化对象 的相同方法或属性, 一份代码,人人可用:为方便理解,我们可以先把prototype 当作是CSS中的 class,在prototype上加方法和属性,那么其它对象就会拥有这些方法和属性, 但这些代码紧有一份!<script>function Person(){this.name = '张三'; this

一招搞定谷歌搜索、谷歌学术无法访问的问题

最近,谷歌搜索.谷歌学术"突然"无法访问了?我百思不得其解啊,禁不住想问一下:前辈们,你们这是要怎样?我们写个论文容易吗?怒火燃尽,言归正传,其实要解决这个问题也是很简单的,原理不赘述,直接上菜.以下谨代表个人意见,大仙们有好的方法记得留言共享讨论,谢谢! 方法一:修改hosts文件 首先,用记事本打开系统目录C:\Windows\System32\drivers\etc下的hosts文件: 然后,在hosts文件的最下方追加以下四个IP地址,保存,退出. 209.116.186.21

教你一招搞定微信朋友圈照片模糊不清

我们在微信朋友圈发照片时会发现图片变模糊了,有一些齿边,不够清晰,这是因为微信默认启用了图片压缩功能,减小图片大小,节省流量.有强迫症的同学肯定会有不爽的赶脚,ytkah教你一招搞定微信朋友圈照片模糊不清. 1.发送照片的时候,点击右下角的“+”号按钮,然后选择“照片”. 2.选中要发送的照片后,点击左下角的“预览”(这个是重点).在预览照片的左下角看到一个“原图”单选,点中后发送,就可以将未压缩的原照片进行发送了. 这样选原图发送朋友圈,照片就不会模糊了,赶紧去试试吧!

2招搞定压力,远离焦虑失眠狂躁

转自 作者:foruok 链接:http://www.jianshu.com/p/3f15766ec487 來源:简书 压力管理 本文以技术管理者为例来讲压力管理,实际上提到的 ABC .暂停.宣泄等方式适用于大多数人. 心理学家 Richard S. Lazarus(拉扎勒斯)提出:压力是由于事件和责任超出个人应对能力范围时所产生的焦虑状态(紧张状态). 当一位开发者刚刚走上管理岗位时,极容易产生压力--原来他只需要管理好自己,搞定开发任务即可,现在他不但要搞定自己,还要管理下属,还要与产品.

桌面右键新建文件不见了?一招搞定

中午发现电脑桌面右击的时候,新建文件不见了,这时候肯定是我又安装了什么软件导致的! 很简单,基本几秒就搞定! 按"Ctrl+R" 输入"regedit" 搜索"ContextMenuHandlers" 找到"New"目录>更改他的值为"{D969A300-E7FF-11d0-A93B-00A0C90F2719}" 假如没有"New"这个目录,直接新建项就行,然后值同上改! 最后确定

如何翻译PPT文档?PPT文档翻译一招搞定

PPT文档怎么翻译?PPT文件中有需要翻译的内容的时候,你还在一个个的复制进网页中搜索然后进行翻译吗?这个方法已经淘汰了,不仅麻烦,还拉低你的工作效率,今天小编来为大家介绍一个翻译PPT文档的方法,教你摆脱死板的翻译方法,翻译PPT也可以轻松搞定!准备工具:文档翻译器还需要提前准备好需要翻译的PPT文件,当然电脑也少不了,这是一个基本的辅助工具哦.好啦,上面的工作就绪后,开始翻译啦:1:打开文档翻译器后,点击左侧功能栏中的文档翻译功能,之后点击页面内的[点击上传文档]按钮添加要进行翻译的PPT文

【】五句话搞定JavaScript作用域

JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C#中存在块级作用域,即:大括号也是一个作用域.  Java  C# 在JavaScript语言中无块级作用域 1 2 3 4 5 6 7 function Main(){     if(1==1){         var name = 'seven';     }     console.log(n

来来来,一起五句话搞定JavaScript作用域

JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一."JavaScript中无块级作用域" 在Java或C#中存在块级作用域,即:大括号也是一个作用域. public static void main () {    if(1==1){         String name = "seven";     }     System.out.println(name); }//