使用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中OnLoad几种使用方法
Dec 15 Javascript
用JS提交参数创建form表单在FireFox中遇到的问题
Jan 16 Javascript
使用闭包对setTimeout进行简单封装避免出错
Jul 10 Javascript
js 走马灯简单实例
Nov 21 Javascript
浅析jquery ajax异步调用方法中不能给全局变量赋值的原因及解决方法
Jan 10 Javascript
EasyUI实现第二层弹出框的方法
Mar 01 Javascript
jquery UI Datepicker时间控件的使用方法(加强版)
Nov 07 Javascript
js判断浏览器是否支持严格模式的方法
Oct 04 Javascript
jquery中关于bind()方法的使用技巧分享
Mar 30 jQuery
JS实现移动端触屏拖拽功能
Jul 31 Javascript
Javascript 关于基本类型和引用类型的个人理解
Nov 01 Javascript
给原生html中添加水印遮罩层的实现示例
Apr 02 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
回答PHPCHINA上的几个问题:URL映射
2007/02/14 PHP
PHP 加密解密内部算法
2010/04/22 PHP
php gd2 上传图片/文字水印/图片水印/等比例缩略图/实现代码
2010/05/15 PHP
thinkphp普通查询与表达式查询实例分析
2014/11/24 PHP
PHP里的单例类写法实例
2015/06/25 PHP
使用PHPCMS搭建wap手机网站
2015/09/20 PHP
jQuery中的常用事件总结
2009/12/27 Javascript
jQuery getJSON()+.ashx 实现分页(改进版)
2013/03/28 Javascript
js中switch case循环实例代码
2013/12/30 Javascript
Javascript 实现图片无缝滚动
2014/12/19 Javascript
javascript制作的cookie封装及使用指南
2015/01/02 Javascript
JS获取Table中td值的方法
2015/03/19 Javascript
javascript生成img标签的3种实现方法(对象、方法、html)
2015/12/25 Javascript
JS获取地址栏参数的两种方法(简单实用)
2016/06/14 Javascript
js实现鼠标左右移动,图片也跟着移动效果
2017/01/25 Javascript
Javascript实现跨域后台设置拦截的方法详解
2017/08/04 Javascript
JavaScript碎片—函数闭包(模拟面向对象)
2019/03/13 Javascript
基于vue的video播放器的实现示例
2021/02/19 Vue.js
[16:56]教你分分钟做大人:司夜刺客
2014/10/30 DOTA
11个并不被常用但对开发非常有帮助的Python库
2015/03/31 Python
Python实现的插入排序算法原理与用法实例分析
2017/11/22 Python
浅谈Python NLP入门教程
2017/12/25 Python
python中join()方法介绍
2018/10/11 Python
windows10下安装TensorFlow Object Detection API的步骤
2019/06/13 Python
python 制作本地应用搜索工具
2021/02/27 Python
利用CSS3制作简单的3d半透明立方体图片展示
2017/03/25 HTML / CSS
HTML5 常用语法一览(列举不支持的属性)
2010/01/26 HTML / CSS
科颜氏美国官网:Kiehl’s美国
2017/01/31 全球购物
CHRONEXT英国:您的首选奢华腕表目的地
2020/03/30 全球购物
机械制造专业个人的自我评价
2013/12/28 职场文书
2014年文学毕业生自我鉴定
2014/04/23 职场文书
2014年物流工作总结
2014/11/25 职场文书
2014年科室工作总结范文
2014/12/19 职场文书
英语教师个人总结
2015/02/09 职场文书
农村党员干部承诺书
2015/05/04 职场文书
医务人员医德医风心得体会
2016/01/25 职场文书