使用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 相关文章推荐
解决jquery异步按一定的时间间隔刷新问题
Dec 10 Javascript
Three.js源码阅读笔记(基础的核心Core对象)
Dec 27 Javascript
JS实现仿百度输入框自动匹配功能的示例代码
Feb 19 Javascript
分享十五款 jQuery 社交网络分享插件
May 16 Javascript
Angular多选、全选、批量选择操作实例代码
Mar 10 Javascript
js评分组件使用详解
Jun 06 Javascript
微信小程序开发之map地图实现教程
Jun 08 Javascript
JS去掉字符串中所有的逗号
Oct 18 Javascript
使用Vue做一个简单的todo应用的三种方式的示例代码
Oct 20 Javascript
laydate如何根据开始时间或者结束时间限制范围
Nov 15 Javascript
小程序开发中如何使用async-await并封装公共异步请求的方法
Jan 20 Javascript
微信小程序获取地理位置及经纬度授权代码实例
Sep 18 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&java(二)
2006/10/09 PHP
php 文件上传系统手记
2009/10/26 PHP
php imagecreatetruecolor 创建高清和透明图片代码小结
2010/05/15 PHP
php中的curl_multi系列函数使用例子
2014/07/29 PHP
用PHP去掉文件头的Unicode签名(BOM)方法
2017/06/22 PHP
PHP的mysqli_stat()函数讲解
2019/01/23 PHP
javascript (用setTimeout而非setInterval)
2011/12/28 Javascript
js中页面的重新加载(当前页面/上级页面)及frame或iframe元素引用介绍
2013/01/24 Javascript
3种Jquery限制文本框只能输入数字字母的方法
2014/12/03 Javascript
jQuery中closest()函数用法实例
2015/01/07 Javascript
JavaScript操作Oracle数据库示例
2015/03/06 Javascript
vue插件tab选项卡使用小结
2016/10/27 Javascript
JS处理数据四舍五入(tofixed与round的区别详解)
2017/10/26 Javascript
微信小程序出现wx.navigateTo页面不跳转问题的解决方法
2017/12/26 Javascript
Nodejs 和 Electron ubuntu下快速安装过程
2018/05/04 NodeJs
node中实现删除目录的几种方法
2019/06/24 Javascript
ES6 Map结构的应用实例分析
2019/06/26 Javascript
vue v-for 使用问题整理小结
2019/08/04 Javascript
js实现随机div颜色位置 类似满天星效果
2019/10/24 Javascript
vue-router懒加载的3种方式汇总
2021/02/28 Vue.js
[00:32]DOTA2上海特级锦标赛 COL战队宣传片
2016/03/04 DOTA
[01:10:48]完美世界DOTA2联赛PWL S2 GXR vs PXG 第一场 11.18
2020/11/18 DOTA
python selenium 获取标签的属性值、内容、状态方法
2018/06/22 Python
Python统计纯文本文件中英文单词出现个数的方法总结【测试可用】
2018/07/25 Python
Python BS4库的安装与使用详解
2018/08/08 Python
python获取引用对象的个数方式
2019/12/20 Python
5分钟弄清楚html5的drag and drop(小结)
2019/04/10 HTML / CSS
阿波罗盒子:Apollo Box
2017/08/14 全球购物
奥利奥广告词
2014/03/20 职场文书
2014年教学工作总结
2014/11/13 职场文书
合伙经营协议书范本(通用版)
2014/12/03 职场文书
研究生给导师的自荐信
2015/03/06 职场文书
婚宴新郎致辞
2015/07/28 职场文书
2019年市场部个人述职报告(三篇)
2019/10/23 职场文书
JavaScript的function函数详细介绍
2021/11/20 Javascript
Python OpenCV实现图形检测示例详解
2022/04/08 Python