本教程介绍了在开发者工具中调试任何 JavaScript 问题的基本工作流程。已读 或观看本教程的视频版本。
重现错误
找到一系列可一致重现 bug 的操作始终是 调试。
- 在新标签页中打开此演示。
- 在 Number 1 框中输入
5
。 - 在 Number 2 框中输入
1
。 - 点击添加数字 1 和 2。按钮下方的标签显示
5 + 1 = 51
。取得的成效 应为6
。这就是您要修复的 bug。
在此示例中,5 + 1 的结果是 51。应该是 6。
熟悉“来源”面板界面
开发者工具为不同的任务(例如更改 CSS、分析页面)提供了许多不同的工具 加载性能、监控网络请求等。您可以在 Sources 面板中进行调试 JavaScript。
打开开发者工具并导航到 Sources 面板。
Sources 面板包含三个部分:
- 包含文件树的 Page 标签页。该页面请求的每个文件都列在此处。
- 代码编辑器部分。在 Page 标签页中选择文件后, 相应文件会显示在此处
Debugger 部分。用于检查网页 JavaScript 的各种工具。
如果开发者工具窗口较宽,默认情况下,Debugger 位于 Code Editor 的右侧。在本例中,Scope 和 Watch 标签页将 Breakpoints、Call stack 和其他部分合并为可收起的部分。
使用断点暂停代码
调试此类问题的常用方法是插入大量 console.log()
语句。
插入代码中,以便在执行脚本时检查值。例如:
function updateLabel() {
var addend1 = getNumber1();
console.log('addend1:', addend1);
var addend2 = getNumber2();
console.log('addend2:', addend2);
var sum = addend1 + addend2;
console.log('sum:', sum);
label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
}
console.log()
方法可以完成此任务,但断点可以更快完成此任务。答
利用断点,你可以在代码执行过程中暂停代码,并检查该时间点的所有值
。与 console.log()
方法相比,断点具有一些优势:
- 使用
console.log()
时,您需要手动打开源代码,找到相关代码,console.log()
语句,然后重新加载页面,以便查看 控制台。有了断点,你甚至无需知道代码的执行情况,就可以暂停在相关的代码上 结构。 - 在
console.log()
语句中,您需要明确指定要 检查。使用断点时,DevTools 会在该时刻显示所有变量的值。 有时,您甚至都不知道的变量会影响您的代码。
简而言之,与 console.log()
方法相比,断点可帮助您更快地找到和修复 bug。
如果您退一步思考这款应用的运作方式,就可以有根据地猜测,
在与5 + 1 = 51
click
添加数字 1 和数字 2 按钮。因此,您可能需要大约在以下时间暂停代码:
click
监听器所执行的一系列事件。借助事件监听器断点,您可以实现这一点:
- 在 Debugger 部分,点击 Event Listener Breakpoints 以展开 部分。开发者工具会显示一系列可展开的事件类别,例如 Animation 和 剪贴板。
- 在鼠标事件类别旁边,点击 arrow_right 展开。 DevTools 会显示鼠标事件(例如 click 和 mousedown)的列表。每个事件旁边都有一个复选框。
选中 click 复选框。DevTools 现已设置为在出现任何
click
时自动暂停 事件监听器。返回到演示页面,再次点击 Add Number 1 and Number 2。DevTools 会暂停演示并 会在 Sources 面板中突出显示一行代码。开发者工具应在以下行上暂停 代码:
function onClick() {
如果是在其他代码行暂停,请按 Resume 继续执行脚本,直到暂停到正确的代码行。
事件监听器断点只是开发者工具中提供的众多断点类型之一。时间是 因为每种类型最终都可以帮助您调试不同的 尽快处理场景如需了解何时以及如何暂停,请参阅使用断点暂停代码 使用每种类型。
单步调试代码
导致错误的一种常见原因是脚本执行顺序错误。单步调试代码 您可以逐行检查代码的执行情况,并准确找出 它的执行顺序与预期不同立即试用:
在开发者工具的 Sources 面板上,点击 step_into Step into next function call(进入下一个函数调用),一次一行地逐步执行
onClick()
函数。DevTools 突出显示了以下代码行:if (inputsAreEmpty()) {
点击 step_over Step over next function call。
开发者工具会执行
inputsAreEmpty()
,而不进入它。请注意,开发者工具会跳过几行 代码。这是因为inputsAreEmpty()
的计算结果为 false,因此if
语句的块 代码没有执行。
这就是单步调试代码的基本思路。如果您查看 get-started.js
中的代码,可以
您会发现 bug 可能位于 updateLabel()
函数中的某个位置。你不必逐个检查
可以使用其他类型的断点来暂停更接近
bug 所在的位置。
设置代码行断点
代码行断点是最常见的断点类型。收到特定的一行 代码,请使用代码行断点:
查看
updateLabel()
中的最后一行代码:label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
在代码的左侧,您可以看到这行代码的行号, 32。点击 32。开发者工具会在 32 上方放置一个蓝色图标。这意味着 添加代码行断点现在,开发者工具始终会在此代码行 。
点击 Resume 继续执行脚本。通过 脚本将继续执行,直到到达第 32 行。在第 29、30 和 31 行,DevTools 会在其声明旁显示
addend1
、addend2
和sum
的值。
在此示例中,开发者工具会在第 32 行代码行断点处暂停。
检查变量值
addend1
、addend2
和 sum
的值看起来很可疑。它们会用英文引号引起来
表示它们是字符串。这个假设很适合用来解释错误的原因。现在
是时候收集更多信息了。开发者工具提供了许多用于检查变量的工具
值。
方法 1:检查范围
当您在某行代码上暂停时,Scope 标签页会显示哪些局部和全局变量 以及每个变量的值。它还显示闭包变量, 。如果您未暂停代码行,则 Scope 标签页为空。
双击变量值即可进行修改。
方法 2:监视表达式
通过 Watch 标签页,您可以监控变量值随时间变化的情况。Watch 并不仅限于变量。您可以存储任何有效的 JavaScript Watch 标签页中的值。
立即试用:
- 点击观看标签页。
- 点击 add 添加监视表达式。
- 输入
typeof sum
。 - 按 Enter 键。开发者工具显示
typeof sum: "string"
。冒号右侧的值为 计算结果。
此屏幕截图显示了创建 typeof sum
手表后的 Watch 标签页(右下角)
表达式。
和我们猜想的一样,sum
的求值结果本应是数字,而实际值却是字符串。您现在已确认
这就是导致错误的原因
方法 3:控制台
除了查看 console.log()
消息之外,您还可以使用控制台评估
JavaScript 语句。在调试方面,您可以使用控制台来测试潜在修复方法
以检测是否存在 bug。立即试用:
- 如果您尚未打开控制台抽屉式导航栏,请按 Esc 将其打开。它会在 打开开发者工具窗口
- 在控制台中,输入
parseInt(addend1) + parseInt(addend2)
。此语句之所以有效,是因为您 会在addend1
和addend2
在作用域内的一行代码上暂停。 - 按 Enter 键。开发者工具会评估语句并输出
6
,这是您期望的结果 要生成的演示
此屏幕截图显示了对 parseInt(addend1) + parseInt(addend2)
求值后的 Console 抽屉式导航栏。
应用修正
您已找到 bug 的修复。接下来要做的就是尝试通过修改代码来解决问题, 重新运行演示您无需退出开发者工具即可应用修复程序。您可以修改 JavaScript 代码 。立即试用:
- 点击 Resume 继续执行脚本。
- 在代码编辑器中,将第 31 行
var sum = addend1 + addend2
替换为var sum = parseInt(addend1) + parseInt(addend2)
。 - 按 Command + S (Mac) 或 Ctrl + S(Windows、Linux)以保存更改。
- 点击 label_off 停用断点。 其颜色会变为蓝色,表示已启用。完成此设置后,DevTools 会忽略 您设置的断点
- 试用不同的值。演示现在可正确计算。
后续步骤
本教程仅介绍了两种设置断点的方法。DevTools 还提供了许多其他方式 包括:
- 仅在满足您指定的条件时触发的条件断点。
- 发生已捕获或未捕获异常时触发的断点。
- 当请求的网址与您提供的子字符串匹配时触发的 XHR 断点。
如需了解何时以及如何使用每种类型,请参阅使用断点暂停代码。
有几个代码单步执行控件未在本教程中进行说明。请参阅单步跳过 代码行了解详情。