使用Chrome调试JavaScript的断点设置和调试技巧


Posted in Javascript onDecember 16, 2014

你是怎么调试 JavaScript 程序的?最原始的方法是用 alert() 在页面上打印内容,稍微改进一点的方法是用 console.log() 在 JavaScript 控制台上输出内容。嗯~,用这两种土办法确实解决了很多小型 JavaScript 脚本的调试问题。不过放着 Chrome 中功能越发强大的开发者工具不用实在太可惜了。本文主要介绍其中的 JavaScript断点设置和调试功能,也就是其中的 Sources Panel(以前叫 Scripts)。如果你精通 Eclipse 中的各种 Java 调试技巧,那么这里的概念都是类似。写作本文时使用的 Chrome 版本为 25.0.1364.172。

基本环境

使用Chrome调试JavaScript的断点设置和调试技巧

SourcesPanel 的左边是内容源,包括页面中的各种资源。其中,又分 Sources 和 Content scripts。Sources 就是页面本身包含的各种资源,它是按照页面中出现的域来组织的,这是我们要关注的。异步加载的 js 文件,在加载后也会出现在这里的。Content scripts 是 Chrome 的一种扩展程序,它是按照扩展的ID来组织的,这类扩展实际也是嵌入在页面中的资源,它们也可以读写DOM。编写、调试这类扩展的开发者才要关心它们,如果你的浏览器没安装任何扩展,那么Content scripts 就看不到任何东西。

Sources Panel 的中间主区域用于展示左边资源文件的内容。

Sources Panel 的右边是调试功能区,最上面的一排按钮分别是暂停/继续、单步执行、单步跳入、单步跳出、禁用/启用所有断点。下面是各种具体的功能区。稍后介绍。

注意,左右两边的区域默认可能收缩在两侧没有显示出来,点击两侧的伸缩按钮使用Chrome调试JavaScript的断点设置和调试技巧使用Chrome调试JavaScript的断点设置和调试技巧展示出来。左边区域展示出来时默认是自动收缩状态,点击旁边的 pin 按钮使用Chrome调试JavaScript的断点设置和调试技巧就不会缩回去了。

最下面还有一些功能按钮很有用。

在源代码上设置断点

通过左边的内容源,打开对应的 JavaScript 文件,鼠标点击文件的行号就可以设置和删除断点。添加的每个断点都会出现在右侧调试区的 Breakpoints 列表中,点击列表中断点就会定位到内容区的断点上。如果你有多个文件、多个断点的话,利用Breakpoints 列表中的断点快速定位非常方便。

使用Chrome调试JavaScript的断点设置和调试技巧

对于每个已添加的断点都有两种状态:激活和禁用。刚添加的断点都是激活状态,禁用状态就是保留断点但临时取消该断点功能。在Breakpoints 列表中每个断点前面都有一个复选框,取消选中就将禁用该断点。断点位置的右键菜单中也可以禁用断点。也可以在右侧功能区上面使用Chrome调试JavaScript的断点设置和调试技巧按钮临时禁用所有已添加的断点,再点一下恢复原状态。

条件断点:在断点位置的右键菜单中选择“Edit Breakpoint...”可以设置触发断点的条件,就是写一个表达式,表达式为 true 时才触发断点。查看断点的环境调用栈(Call Stack):在断点停下来时,右侧调试区的 Call Stack 会显示当前断点所处的方法调用栈,比如有一个函数 g() 其中又调用了函数 f() ,而我在 f() 中设置了一个断点,那么我在 console 中执行函数 g() 的时候会触发断点,其调用栈显示如下:

使用Chrome调试JavaScript的断点设置和调试技巧

最上面是 f(),然后是 g()。调用栈中的每一层叫做一个 frame,点击每个 frame 可以跳到该 frame 的调用点上。

使用Chrome调试JavaScript的断点设置和调试技巧

此外,还可以在 frame 上用右键菜单重新开始执行当前 frame,也就是从该 frame 的开始处执行。比如在函数 f() 的 frame 上 Restart Frame, 断点就会跳到 f() 的开头重新执行,context 中的变量值也会还原。这样结合变量修改和编辑代码等功能,就可以在当前 frame 中反复进行调试,而不用刷新页面重新触发断点了。查看变量

使用Chrome调试JavaScript的断点设置和调试技巧

Call Stack 列表的下方是 Scope Variables 列表,在这里可以查看此时局部变量和全局变量的值。执行选择的代码

使用Chrome调试JavaScript的断点设置和调试技巧

在断点调试时,可以用鼠标选择想要查看的变量或表达式,然后右键菜单执行“Evaluate in Console”,就可以看到该表达式的当前的值了。中断下次要执行的 JavaScript 语句右侧调试区的上面的“中断/继续”按钮还有一个功能,在没有触发断点时,点一下这个按钮就会进入“准备”中断的状态,页面下一次执行 JavaScript 语句时会自动中断,比如触发了一个点击动作时会执行的代码。临时修改 JavaScript 代码通常我们在调试代码时习惯:修改代码→刷新页面→重新检查,这么一个循环。但其实 Chrome 中可以临时修改 JS 文件中的内容,保存(Ctrl+S)就可以立即生效,结合 Console 等功能就可以立即重新调试了。但注意这个修改是临时的,刷新页面修改就没了。

异常时断点

在界面下方能看到使用Chrome调试JavaScript的断点设置和调试技巧按钮,它是设置程序运行时遇到异常时是否中断的开关。点击该按钮会在3种状态间切换:

使用Chrome调试JavaScript的断点设置和调试技巧默认遇到异常不中断

使用Chrome调试JavaScript的断点设置和调试技巧遇到所有异常都会中断,包括已捕获的情况

使用Chrome调试JavaScript的断点设置和调试技巧仅在出现未捕获的异常时才中断

主要解释一下状态2和状态3的区别

try{
throw 'a exception';
}catch(e){
console.log(e);
}

上面 try 里面的代码会遇到异常,但是后面的 catch 代码能够捕获该异常。如果是所有异常都中断,那么代码执行到会产生异常的 throw 语句时就会自动中断;而如果是仅遇到未捕获异常才中断,那么这里就不会中断。一般我们会更关心遇到未捕获异常的情况。

在 DOM 元素上设置断点

有时候我们需要监听某个 DOM 被修改情况,而不关心是哪行代码做的修改(也可能有多处都会对其做修改)。那么我们可以直接在 DOM 上设置断点。

使用Chrome调试JavaScript的断点设置和调试技巧

如图所见,在元素审查的 Elements Panel 中在某个元素上右键菜单里可以设置三种不同情况的断点:子节点修改自身属性修改自身节点被删除选中之后,Sources Panel 中右侧的 DOM Breakpoints 列表中就会出现该 DOM 断点。一旦执行到要对该 DOM 做相应修改时,代码就会在那里停下来,如下图所示。使用Chrome调试JavaScript的断点设置和调试技巧

XHR 断点

右侧调试区有一个 XHR Breakpoints,点击+ 并输入 URL 包含的字符串即可监听该 URL 的 Ajax 请求,输入内容就相当于 URL 的过滤器。如果什么都不填,那么就监听所有 XHR 请求。一旦 XHR 调用触发时就会在 request.send() 的地方中断。

按事件类型触发断点

右侧调试区的Event Listener 列表,这里列出了各种可能的事件类型。勾选对应的事件类型,当触发了该类型的事件的 JavaScript 代码时就会自动中断。

调试快捷键

使用Chrome调试JavaScript的断点设置和调试技巧所有开发工具中的快捷键都可以在界面右下角的设置中查到。断点调试时一般用的是 F8、F10、F11或 Shitf+F11,但在 Mac OS 上 F10 等功能键可能与系统默认的快捷键冲突。没关系,它们分别可以用 Cmd+/ 、Cmd+'、Cmd+; 、Shift+Cmd+; 代替。//@ sourceURL 给 eval 出来的代码命名有时候一些非常动态的代码是以字符串的形式通过 eval() 函数在当前 Javascript context 中创建出来,而不是作为一个独立的 js 文件加载的。这样你在左边的内容区就找不到这个文件,因此很难调试。其实我们只要在 eval 创建的代码末尾添加一行 “//@ sourceURL=name“就可以给这段代码命名(浏览器会特殊对待这种特殊形式的注释),这样它就会出现在左侧的内容区了,就好像你加载了一个指定名字的 js 文件一样,可以设置断点和调试了。下图中,我们通过 eval 执行了一段代码,并利用sourceURL 将它命名为dynamicScript.js ,执行后左侧内容区就出现了这个“文件”,而它的内容就是 eval 的中的内容。使用Chrome调试JavaScript的断点设置和调试技巧还可以看看这个给动态编译出来的CoffeeScript 代码命名的示例:

var coffee = CoffeeScript.compile(code.value)+ "//@ sourceURL=" + (evalName.value || "Coffeeeeeeee!");
eval(coffee);

实际上,//@ sourceURL 不仅仅可以用在 eval 的代码中,任何 js 文件、甚至是 Javascript Console 输入的代码都可以用,效果一样!格式化代码(Pretty Print)使用Chrome调试JavaScript的断点设置和调试技巧按钮用于把杂乱的代码重新格式化为漂亮的代码,比如一些已被压缩的 js 文件基本没法看、更没法调试。点一下格式化,再点一下就取消格式化。使用Chrome调试JavaScript的断点设置和调试技巧美化前
使用Chrome调试JavaScript的断点设置和调试技巧美化后参考资料:Chrome Developer Tools 官方文档

Javascript 相关文章推荐
JavaScript的Function详细
Nov 14 Javascript
javascript中直接写php代码的方法
Jul 31 Javascript
js动态设置div的值下例子
Oct 29 Javascript
详解基于Bootstrap扁平化的后台框架Ace
Nov 27 Javascript
JavaScript中对JSON对象的基本操作示例
May 21 Javascript
ThinkJS中如何使用MongoDB的CURD操作
Dec 13 Javascript
angular中的http拦截器Interceptors的实现
Feb 21 Javascript
javascript 使用正则test( )第一次是 true,第二次是false
Feb 22 Javascript
js中编码函数:escape,encodeURI与encodeURIComponent详解
Mar 21 Javascript
es6学习笔记之Async函数基本教程
May 11 Javascript
JS原生轮播图的简单实现(推荐)
Jul 22 Javascript
详解Vue中组件的缓存
Apr 20 Javascript
node.js中的fs.fchownSync方法使用说明
Dec 16 #Javascript
node.js中的fs.fchown方法使用说明
Dec 16 #Javascript
node.js中的fs.chownSync方法使用说明
Dec 16 #Javascript
node.js中的fs.chown方法使用说明
Dec 16 #Javascript
基于jquery的手风琴图片展示效果实现方法
Dec 16 #Javascript
node.js中的fs.lchownSync方法使用说明
Dec 16 #Javascript
node.js中的fs.lchown方法使用说明
Dec 16 #Javascript
You might like
PHP类的使用 实例代码讲解
2009/12/28 PHP
在Windows XP下安装Apache+MySQL+PHP环境
2015/02/22 PHP
php实现通过cookie换肤的方法
2015/07/13 PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
2015/09/14 PHP
php实现背景图上添加圆形logo图标的方法
2016/11/17 PHP
php删除二维数组中的重复值方法
2018/03/12 PHP
PHP 多任务秒级定时器的实现方法
2018/05/13 PHP
PHP自定义递归函数实现数组转JSON功能【支持GBK编码】
2018/07/17 PHP
yii框架结合charjs统计上一年与当前年数据的方法示例
2020/04/04 PHP
js面向对象设计用{}好还是function(){}好(构造函数)
2011/10/23 Javascript
jQuery之自动完成组件的深入解析
2013/06/19 Javascript
用jquery统计子菜单的条数示例代码
2013/10/18 Javascript
jqGrid增加时--判断开始日期与结束日期(实例解析)
2013/11/08 Javascript
Firefox中使用outerHTML的2种解决方法
2014/06/07 Javascript
Ajax局部更新导致JS事件重复触发问题的解决方法
2014/10/14 Javascript
Jquery跨域获得Json的简单实例
2016/05/18 Javascript
javascript入门之string对象【新手必看】
2016/11/22 Javascript
uploader秒传图片到服务器完整代码
2017/04/22 Javascript
jquery Ajax实现Select动态添加数据
2017/06/08 jQuery
vue中使用axios post上传头像/图片并实时显示到页面的方法
2018/09/27 Javascript
vue-cli3.0 环境变量与模式配置方法
2018/11/08 Javascript
解决vue-router 二级导航默认选中某一选项的问题
2019/11/01 Javascript
vue父子组件的通信方法(实例详解)
2019/11/10 Javascript
Javascript类型判断相关例题及解析
2020/08/26 Javascript
[11:44]Ti9 OG夺冠时刻
2019/08/25 DOTA
Python描述器descriptor详解
2015/02/03 Python
Python Django 实现简单注册功能过程详解
2019/07/29 Python
Python实现图片批量加入水印代码实例
2019/11/30 Python
python和js交互调用的方法
2020/06/23 Python
全球领先的鞋类零售商:The Walking Company
2016/07/21 全球购物
法国娇韵诗官方旗舰店:Clarins是来自法国的天然护肤品牌
2018/06/30 全球购物
MySQL面试题目集锦
2016/04/14 面试题
应用电子技术专业个人求职信
2013/09/21 职场文书
艺术专业大学生自我评价
2013/09/22 职场文书
建筑设计学生的自我评价
2014/01/16 职场文书
2015年保洁工作总结范文
2015/04/28 职场文书