Chrome调试JS中的BUG

这是一篇我认为介绍chrome调试bug的好文章,原文链接:https://www.zhihu.com/question/35667558/answer/530643532

 

分享 Codeburst 上一篇过万赞的 JavaScript 前端 bug 调试教程,至于够不够“淫巧”的标准,不好说,反正绝对称得上实用。教你如何在 Chrome 开发者工具内使用断点来调试代码,彻底摒弃 console.log 调试!

编程新手刚开始查找和修复 bug 还是比较困难的,你可能会随机使用 console.log(),试图让代码正确运行。看了本文再也不用这么干了!

下面就教你一个调 bug 的正确姿势。你会学习如何使用 Chrome 开发者工具设置断点,逐步调试代码。这种工作方法能让你查找和修复 bug 的效率大幅提高。

虽然这篇教程展示的是怎么调试一个具体的 bug,但是整体工作思路对调试任何类型的 JavaScript bug 都是有指导意义的。

步骤1:重现 bug

调试 bug 的第一步就是重现 bug。所谓“重现 bug”就意味着要找到一系列持续导致出现这个 bug 的操作。你可能需要多次重现 bug,所以尽可能地减少不必要的步骤。

按照如下指令来重现本教程需要修复的 bug。

  • 这是我们本教程会使用的网页,确保以新的标签:OPEN DEMO 打开该网页
  • 在 demo 中,在“Number 1”文本框中输入 5
  • 在“Number 2”文本框中输入数字 2
  • 点击“Add Number 1 and Number 2”按钮
  • 查看输入和按钮下方的标签,显示 5 + 1 = 51.

这不,bug 来了,这里结果明显错了,应该是 6。这就是你要修复的 bug。

步骤2:使用断点暂停代码

Chrome 开发者工具(以下简称 DevTools)能让你在代码运行期间暂停代码,并检查此刻所有变量的值。暂停代码的工具叫做 Breakpoint。试试吧:

  • 回到 demo,按 Command+Option(Mac)或 Ctrl+shift+I(Windows,Linux)打开DevTools
  • 点击“Source”标签
  • 点击“Event Listener Breakpoints”(事件监听断点)展开该部分。DevTools 会展示一列可扩展的事件类别,比如 Animation和Clipboard
  • 在“Mouse”事件类别旁边点击“Expand”
  • 检查“click”复选框

 

  • 回到 demo,再次点击“Add Number 1 and Number 2”.DevTools 会暂停 demo,在“Source”面板上高亮显示一行代码,高亮显示的是:
function onClick() {

为啥?

当你选择“Click”时,会在所有的 click 事件上设置一个基于事件的断点。每当节点被点击,并且节点有 click 处理程序时,DevTools 就会在该节点的 click 处理程序的第一行代码处自动暂停。

步骤3:逐步调试代码

导致出现 bug 的一个常见原因就是脚本运行顺序不正确。逐步调试代码能让你过一遍你的代码运行状况,每次一行,准确找出哪里没有按照预期的顺序执行。试试:

  • 在 DevTools 的“Source”面板上,点击“Step into next function call”

 

这个按钮能让你逐步查看 onClick() 函数的运行,每次一行。当 DevTools 高亮显示如下一行代码时就停止:

if (inputsAreEmpty()) {

 

  • 现在点击“Step over next function call”按钮

 

 

这会让 DevTools 执行 inputsAreEmpty() 而不进入它。注意 DevTools 跳过了几行代码,这是因为 inputsAreEmpty() 求值结果为 false,所以 if 语句的代码块没有运行。

这就是逐步调试代码的基本理念。如果你查看 get-started.js 中的代码,会发现 bug 可能在 updateLabel() 函数的某个位置。你不必逐行看完所有代码,可以换用另一种断点,在靠近该 bug 的位置暂停代码运行。

步骤4:设置另一个断点

代码行断点是最常见的断点类型。如果想在执行到某一行代码时暂停,就使用代码行断点。试试吧:

  • 查看 updateLabel() 中的最后一行代码,如下所示:
label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;

在代码的左侧,你可以看到这行代码的具体行数:32。点击 32,DevTools 会在 32 上放置一个蓝色图标,表示在这里设置了一个代码行断点。这样以来,DevTools 总会在执行这行代码前暂停。

点击“Resume script execution”按钮

 

这段脚本会持续执行,直到到达你设置了断点的那行代码。

  • 查看 updateLabel() 中已执行的代码行。DevTools 打印输出 addend1,addend2 和 sum 的值。

Sum 的值看着很有问题,求值结果应该是数字才对,但这里却是字符串。这可能就是造成 bug 的原因。

步骤5:检查变量值

造成 bug 的另一个常见原因就是变量或函数产生了异常值。很多开发者会使用 console.log() 来查看值随着时间变化的情况,但使用 console.log() 枯燥又麻烦,而且没有效率。究其原因有二,首先你可能需要手动编辑代码,而且需要大量调用 console.log();其次,你可能无法确定哪个变量和 bug 有关,所以你需要记录很多变量。

DevTools 上有个替代 console.log() 的工具叫 Watch Expressions,使用 Watch Expressions 能够监控变量值随着时间的变化。正如其名,Watch Expressions 并不仅仅能监控变量,你可以将任何有效的 JavaScript 表达式存储在 Watch Expressions 中。试试吧:

  • 在 DevTools 上的“Source”面板上点击“Watch”,然后这部分会展开。
  • 点击“Add Expression”

 

  • 输入 typeof sum
  • 按 Enter 键,DevTools 会显示 typeof sum: "string"。冒号右边的值就是你的 Watch Expression 的结果。

和我们猜的一样,sum 被处理成了字符串,而本应是个数字。这就是 demo 上的 bug 的来源。

DevTools 中另一个能取代 console.log() 的工具是 Console,可以使用 Console 对任意 JavaScript 语句求值。很多开发者通常在调 bug 时使用 Console 覆盖变量值。在本教程这个例子中,Console 能帮你测试刚发现的 bug 的潜在修复方法。试试:

  • 如果还没打开 Console,按 Escape 键打开它,会在你的 DevTools 窗口底部打开。
  • 在 Console 中输入 parseInt(addend1) + parseInt(addend2)
  • 按 Enter 键,DevTools 会对语句求值,输出 6,也就是开头 Demo 中我们预期程序应该输出的结果。

 

步骤6:应用修复方法

确定一种修复 bug 的潜在方法后,剩下的工作就是编辑代码,尝试修复,并重新运行 demo。不必离开 DevTools 界面就能应用修复。你可以直接在 DevTools UI 里直接编辑 JavaScript 代码。试试吧:

  • 在 DevTools 的“Source”面板的代码编辑器中,用 var sum = parseInt(addend1) + parseInt(addend2) 替换 var sum = addend1 + addend2。就是当前暂停位置上面的那行代码。
  • 按 Command+S(Mac)或 Ctrl+S(Windows,Linux)保存修改。代码背景色变为红色,表示脚本已经在 DevTools 中被修改。
  • 点击“Deactivate breakpoints”

 

它变为蓝色表示正处于活动状态。如果这样设置,DevTools 会忽略你设置的任何断点。

  • 点击“ Resume script execution”

可以用不同的值试试吧,现在 demo 应该能正确地计算出 sum 值了。

注意:该工作流程只对运行在浏览器中的代码应用修正。它不会为所有运行你的页面的用户修正代码。要想实现该目的,需要修正运行在提供页面的服务器上的代码。

以上就是在 DevTools 中调试 JavaScript bug 的基础知识,本文只介绍了两种设置断点的方法,此外还有不少很多其它方法,比如:

  • 仅在满足你指定的条件时触发的条件断点。
  • 发生已捕获或未捕获异常时触发的断点。
  • 当请求的网址和你提供的子字符串匹配时触发的 XHR 断点。