在 Chrome 中调试 JS 代码,那你不得不与 Chrome DevTools 的 Sources 面板打交道,因此文章主要经过介绍 Sources 面板上的各部分功能来介绍如何调试网页中的 JS。git
先来认识一下 Sources 面板(以个人 Github 首页举例)。github
能够看到面板被分为左中右三个部分,左边是文件导航,中间是文件的具体内容,右边能够统称为调试面板。整个面板就像一个 IDE,因此仍是挺亲切的。ajax
Sources:这个面板很好理解,展现了网页所用到的全部文件框架
Content scripts:Content scripts 指的是 Chrome 拓展注入在网页中的脚本。好比我安装了一个叫 JSONView 的 Chrome 拓展,打开个人 Content scripts 面板会看到:dom
Snippets:Snippets 的含义是片断,在这里指的是一小段程序,这个一小段程序跟在其余地方不同的是,能够访问这个页面中的变量和函数等。函数
中间面板的其余操做都比较显而易见,只是有 4 点须要简单提一下。测试
标记 一、2 处能够隐藏/展开左右两个面板,标记 3 处格式化代码,使得代码变得易于阅读,当代码被压缩时尤为有用。另外须要提一下的是打开文件的快捷方式,能够用 Cmd + p / Ctrl + p 在任何一个功能面板上搜索一个文件,按 enter 键在 Sources 面板上打开。debug
右边的调试面板比较复杂,须要借助调试的例子来解释做用。不过咱们能够先大概熟悉一下:调试
右侧的面板为上下结构,上面是一组功能按钮,下面由不少面板组成,这些面板中,看名字大概能知道第二个显示的是调用栈,从四个开始就是各类类型的断点。那真相是什么呢?咱们下面结合调试实例来解释这些按钮/面板的功能。
本文用到的测试代码为本身所写的 Demo。
打开一个文件,中间的面板中显示了代码,代码的左侧有代码行号,代码行号所在的位置叫作行号槽,点击行号槽,为相应的行添加断点,并在相应的行号上面加上一个相似肩章的五边形图标。特别提一下的是,这个图标的颜色是蓝色的。以下:
另外,若是一条语句由多行组成,若是在这条语句的行中添加断点的话,那么断点将会被加到下一条语句。举例以下:
在上面的代码中,你能够在 13 行添加断点,但若是你想在 14-17 行添加断点的话,那么断点将会被添加到 19 行。另外,你也不能为空行添加断点,那也会被添加到下一条语句上。好比你想在 18 行添加断点,但实际会被添加到 19 行。
条件断点
右键一个没有添加断点的行号,选择 "Add conditional breakpoint",输入你的条件,当条件知足时,断点才会生效。回车后,效果以下:
能够看见,条件断点跟通常断点的区别就是颜色变成了黄色。
行内断点
以前有人在评论里问,为何个人这个系列文章要加一个 v57 这个前提,行内断点就是一个很好的回答。行内断点是从 Chrome(v55) 才有的一个功能,意思是你能够在一行内添加多个断点。看下面的例子:
跟前面添加断点方式同样,我先在 15 行添加了一个断点,当程序中断在 15 行时,出现了上图的例子。但与通常的例子不一样的是,上面有 3 处标红的位置,表示 3 处断点。但第 1 个断点跟后 2 个不同的是,第 1 个断点是默认处于激活状态,然后 2 个则不是,只有点击激活后才能生效。
右键行号槽的时候,第一个选项老是:"Blackbox Script"。
那什么是黑盒脚本呢?
咱们写项目时,不少时候是要引用第三方库或框架的,当咱们调试时,调试的对象应该是咱们本身写的代码,但不少时候,咱们常常在焦灼地进行下一步下一步时,忽然代码跳到了第三方库或框架的源码上去,这让咱们焦灼的心里更添了一把柴火。黑盒脚本就是用来解决这个问题的。它可以将一个脚本文件标记为 "Blackbox Script",那么咱们就永远不可能进入这个文件内部,这个文件对咱们来说就是一个黑盒子。为何要强调“永远”呢?由于不只普通的断点不能访问这个被标记了的脚本,其余的,好比说 DOM 断点、事件断点等等都没法访问那个脚本文件内部。
这个面板会显示你全部的经过行号留下的断点。你能够右键管理某个或所有断点:
除了普通的中断类型,咱们下面再介绍几款其余类型的。
在 Elements 面板,右键 body 元素,插入 "attribute modifications breakpoint",在 Sources 面板中显示以下:
查看 DOM 断点的详细信息请查看另外一篇博客:Elements
XHR 断点跟 DOM 断点很相似,经过 XHR 断点能够很容易的找到 ajax 调用的触发点和调用堆栈。最新的 Chrome DevTools 中要么为全部 ajax 调用添加断点,要么都不添加断点。
展开 Event Listener Breakpoints 能够看到一组事件类型,展开一个事件类型能够看到具体的事件名称。
每一个事件名称和事件类型前面都有个复选框,选中即指当页面中触发了所选的事件的话,就会触发中断。
显示全局监听器,在浏览器中 window 是全局对象,因此在 Global Listeners 面板中显示绑定在 window 对象上的事件监听。
这个跟上面几种不同,这个是放在功能按钮组里面的。
选中 "Pause on exceptions" 按钮,如上图,当执行的脚本出现异常时会触发中断。
介绍了如何添加断点的方式以及几款中断类型,下面介绍一下如何利用断点进行调试。
咱们先来介绍几个功能按钮:
Scope 面板显示了你当前定义的全部属性的值,例子如上图。除了 Scope 面板,你还能够在左侧的代码区域,中断的旁边看到语句中包含的变量的值。除此之外,你还能够把鼠标放在变量上面,也显示对应变量的值。
Scope 会显示三种类型的值: Local、Closure 和 Global。
当代码中断在一处时,Call Stack 面板会显示代码的执行路径。好比在 a() 中调用了 b(),b() 中调用了 c(),那么中断若是在 c() 内部的话,那么 Call Stack 面板会依次显示 c、b、a。
在 JS 中,咱们经常会写匿名函数,显而易见,在调试时,尤为在查看调用栈时,这样很不友好,因此建议尽可能为每一个函数命名。
若是还记得前面所讲的黑盒脚本(Blackbox Script)的话,这里就再重复一句,是的,黑盒脚本永远不可见,因此你即便在查看调用栈时你也无法看到黑盒脚本里的内容。这种状况下会出现下面这样的结果:
前面讲 Scope 面板时介绍了三种查看中断状态下的变量值,还有一个隐蔽的小技巧也能查看,按 esc 按键打开 Console drawer(不清楚是什么能够看Console),而后在里面输入你想查看的值,回车,bingo~
若是你觉得 Chrome DevTools 就简单看看这些值那就过小瞧她了,在中断状态下,还能动态修改变量的值。好比中断处有个变量叫 v,值是 1,若是我直接按 "Resume script execution" 的话,那么下一次的 v 也是 1,但若是我在按恢复执行按钮以前,我在 Console drawer 中输入 v = 2
回车,那么,下一处的 v 就是 2 了。
还有更厉害的,你不只能够修改变量的值,你还能够修改代码!当程序中断时,你能够在 Sources 面板修改你的代码。
介绍到这,还有一个面板:Watch,下面就讲讲这个。
正如名字所表示的,观察,观察什么呢?主要观察变量。
前面咱们讲过,当程序中断时,能够查看这个状态下的变量的值,但局限是只能一个一个查看,而 Watch 的好处是可让咱们同时查看多个变量。你能够经过 "+" 来添加变量,当添加的变量存在时会显示对应的值,不存在的话则会显示 "not availble"。须要注意的是,这里的变量不会随着代码的执行而发生改变,因此到了下一个状态时,你须要点击刷新按钮来得到关注的变量的新的值。
如今的项目几乎都是通过编译过的,因此当咱们调试时会与编译后的代码打交道,但那并非咱们想要的。不要急,Chrome DevTools 提供了预处理过的代码与源码的映射,主要表如今两点:
不过须要注意的是,上面所讲的能查看源码的前提是 Chrome DevTools 在设置中提供了相应权限,具体是:Settings - Sources - Enable Javascript source maps / Enable CSS source maps,勾选这两项便可。不过,默认状况下就是勾选。