通过这份关于 Chrome DevTools 调试功能的综合参考,探索新的调试工作流。
如需了解调试基础知识,请参阅 Chrome DevTools 中的调试 JavaScript 使用入门。
使用断点暂停代码
设置断点,以便在代码执行过程中暂停代码。如需了解如何设置断点,请参阅使用断点暂停代码。
检查暂停时的值
在执行暂停期间,调试程序会评估当前函数中到达断点之前的所有变量、常量和对象。调试程序会在相应声明旁边内嵌显示当前值。
您可以使用 Console 查询已求值的变量、常量和对象。
悬停时预览类/函数属性
在执行暂停期间,将鼠标悬停在类或函数名称上可预览其属性。
单步调试代码
代码暂停后,请一次调试一个表达式,同时调查控制流和属性值。
单步调试代码行
如果在包含与您正在调试的问题无关的函数的代码行上暂停,请点击 Step over 以执行该函数,而无需步入该函数。
例如,假设您要调试以下代码:
function updateHeader() {
var day = new Date().getDay();
var name = getName(); // A
updateName(name); // D
}
function getName() {
var name = app.first + ' ' + app.last; // B
return name; // C
}
您已于 A
暂停订阅。按 Step over 后,DevTools 会执行您要单步调试的函数(即 B
和 C
)中的所有代码。然后,DevTools 会在 D
处暂停。
单步进入代码行
当您在包含与所调试问题相关的函数调用的代码行上暂停时,点击 Step into 可进一步调查该函数。
例如,假设您要调试以下代码:
function updateHeader() {
var day = new Date().getDay();
var name = getName(); // A
updateName(name);
}
function getName() {
var name = app.first + ' ' + app.last; // B
return name;
}
您已于 A
暂停订阅。按 Step into(进入)后,DevTools 会执行这行代码,然后在 B
上暂停。
退出代码行
如果在与您要调试的问题无关的函数内暂停,请点击 Step out 以执行该函数的其余代码。
例如,假设您要调试以下代码:
function updateHeader() {
var day = new Date().getDay();
var name = getName();
updateName(name); // C
}
function getName() {
var name = app.first + ' ' + app.last; // A
return name; // B
}
您已于 A
暂停订阅。按 Step out 后,DevTools 会执行 getName()
(在本例中仅为 B
)中的其余代码,然后在 C
上暂停。
运行某一行代码之前的所有代码
调试长函数时,可能会有大量代码与您要调试的问题无关。
您可以逐行检查所有代码,但这可能会很繁琐。您可以在感兴趣的代码行中设置代码行断点,然后按 Resume Script Execution ,但还有更快的方法。
右键点击您感兴趣的代码行,然后选择继续到此处。DevTools 会运行到该点之前的所有代码,然后在该行代码暂停。
继续执行脚本
如需在暂停后继续执行脚本,请点击继续执行脚本 。开发者工具会执行脚本,直到下一个断点(如果有)。
强制执行脚本
如需忽略所有断点并强制脚本恢复执行,请点击并按住恢复脚本执行 ,然后选择强制执行脚本 。
更改线程上下文
使用 Web Worker 或 Service Worker 时,点击 Threads 窗格中列出的上下文可切换到该上下文。蓝色箭头图标表示当前选定的上下文。
上图中的会话窗格用蓝色勾勒。
例如,假设您在主脚本和服务工作器脚本中的断点处暂停。您想查看服务工作器上下文的本地和全局属性,但“Sources”面板显示的是主脚本上下文。点击“线程”窗格中的服务工件条目,即可切换到该上下文。
逐步解析以英文逗号分隔的表达式
通过浏览以英文逗号分隔的表达式,您可以调试经过缩减的代码。例如,请参考以下代码:
function foo() {}
function bar() {
foo();
foo();
return 42;
}
bar();
经过缩减后,它包含英文逗号分隔的 foo(),foo(),42
表达式:
function foo(){}function bar(){return foo(),foo(),42}bar();
调试程序会以相同的方式逐步处理此类表达式。
因此,步进行为完全相同:
- 缩减后的代码与原始代码之间。
- 使用源代码映射根据原始代码调试缩减后的代码。换句话说,当您看到英文分号时,即使您要调试的实际源代码经过了缩减,您也始终可以按步调试。
查看和修改局部、闭包和全局属性
在某代码行暂停时,使用 Scope 窗格查看和修改局部、闭包和全局作用域中的属性和变量的值。
- 双击属性值可对其进行更改。
- 不可枚举的属性会显示为灰色。
上图中的范围窗格用蓝色勾勒。
查看当前调用堆栈
在某一行代码处暂停时,您可以使用调用堆栈窗格查看将您带到此处的调用堆栈。
点击某个条目可跳转到调用该函数的代码行。蓝色箭头图标表示 DevTools 当前突出显示的函数。
上图中的调用堆栈窗格用蓝色勾勒。
重启调用堆栈中的函数(帧)
如需观察函数的行为并重新运行该函数,而无需重启整个调试流程,您可以在单个函数暂停时重启该函数的执行。也就是说,您可以在调用堆栈中重启函数的帧。
如需重启帧,请执行以下操作:
- 在断点处暂停函数执行。调用堆栈窗格会记录函数调用的顺序。
在调用堆栈窗格中,右键点击某个函数,然后从下拉菜单中选择重启帧。
如需了解重启帧的运作方式,请考虑以下代码:
function foo(value) {
console.log(value);
bar(value);
}
function bar(value) {
value++;
console.log(value);
debugger;
}
foo(0);
foo()
函数将 0
作为参数,将其记录下来,然后调用 bar()
函数。bar()
函数会依次递增参数。
请尝试按以下方式重启这两个函数的帧:
- 将上述代码复制到新代码段,然后运行该代码。执行会在
debugger
代码行断点处停止。 - 请注意,调试程序会在函数声明旁边显示当前值:
value = 1
。 - 重启
bar()
帧。 - 按
F9
逐一执行值递增语句。 请注意,当前值会增加:value = 2
。 - (可选)在范围窗格中,双击相应值进行修改,然后设置所需值。
请尝试重启
bar()
帧,并多次单步执行增量语句。该值会持续增加。
帧重启不会重置参数。换句话说,重启不会恢复函数调用时的初始状态。而是会将执行指针移至函数的开头。
因此,在重启同一函数时,当前参数值会保留在内存中。
- 现在,在调用堆栈中重启
foo()
帧。 请注意,值再次为0
。
在 JavaScript 中,对实参所做的更改不会在函数之外显示(反映)。嵌套函数会接收值,而不是值在内存中的位置。1. 点击“Resume script execution”(继续执行脚本)(F8
) 以完成本教程。
显示已列入忽略列表的帧
默认情况下,调用堆栈窗格仅显示与您的代码相关的帧,并会忽略添加到 设置 > 忽略列表 的所有脚本。
如需查看包含第三方帧的完整调用堆栈,请在调用堆栈部分下启用显示列入忽略列表的帧。
您可以在此演示页面上试用:
- 在 Sources 面板中,依次打开
src
>app
>app.component.ts
文件。 - 在
increment()
函数中设置断点。 - 在调用堆栈部分,选中或取消选中显示列入忽略列表的帧复选框,然后观察调用堆栈中的相关帧或完整帧列表。
查看异步帧
如果您使用的框架支持,DevTools 可以通过将异步代码的两个部分关联起来来跟踪异步操作。
在本例中,调用堆栈会显示整个调用记录,包括异步调用帧。
复制堆栈轨迹
右键点击 Call Stack 窗格中的任意位置,然后选择 Copy stack trace 将当前调用堆栈复制到剪贴板。
以下是输出示例:
getNumber1 (get-started.js:35)
inputsAreEmpty (get-started.js:22)
onClick (get-started.js:15)
浏览文件树
使用“页面”窗格浏览文件树。
在文件树中对已编写和已部署的文件进行分组
使用框架(例如 React 或 Angular)开发 Web 应用时,由于构建工具(例如 webpack 或 Vite)生成的文件经过了缩减,因此很难浏览源代码。
为帮助您浏览来源,来源 > 页面窗格可以将文件分为两类:
- 已授权。类似于您在 IDE 中查看的源文件。DevTools 会根据构建工具提供的源映射生成这些文件。
- 已部署。浏览器读取的实际文件。通常,这些文件会经过缩减。
如需启用分组功能,请在文件树顶部的三点状菜单下,依次选择 > 按作者/部署时间对文件进行分组 。
从文件树中隐藏已列入忽略列表的来源
为帮助您专注于自己创建的代码,默认情况下,来源 > 网页窗格会将添加到 设置 > 忽略列表 的所有脚本或目录灰显。
如需完全隐藏此类脚本,请依次选择来源 > 网页 > > 隐藏列入忽略列表的来源 。
忽略脚本或脚本模式
忽略脚本以在调试时跳过它。被忽略后,脚本会在调用堆栈窗格中被隐藏,并且在逐行执行代码时,您永远不会进入脚本的函数。
例如,假设您要逐步调试以下代码:
function animate() {
prepare();
lib.doFancyStuff(); // A
render();
}
A
是您信任的第三方库。如果您确信您正在调试的问题与第三方库无关,则可以忽略该脚本。
忽略文件树中的脚本或目录
如需忽略单个脚本或整个目录,请执行以下操作:
- 在 Sources(来源)> Page(网页)中,右键点击某个目录或脚本文件。
- 选择将目录/脚本添加到忽略列表。
如果您未隐藏列入忽略列表的来源,则可以在文件树中选择此类来源,然后在 警告横幅中点击从忽略列表中移除或配置。
或者,您也可以依次前往 设置 > 忽略列表,从列表中移除隐藏的目录和脚本以及已忽略的目录和脚本。
从“编辑器”窗格中忽略脚本
如需从编辑器窗格中忽略脚本,请执行以下操作:
- 打开相应文件。
- 右键点击任意位置。
- 选择向忽略列表添加脚本。
您可以依次前往 设置 > 忽略列表,从忽略列表中移除脚本。
在“调用堆栈”窗格中忽略脚本
如需从调用堆栈窗格中忽略脚本,请执行以下操作:
- 右键点击脚本中的函数。
- 选择向忽略列表添加脚本。
您可以依次前往 设置 > 忽略列表,从忽略列表中移除脚本。
在“设置”中忽略脚本
依次选择 设置 > 忽略列表。
从任何页面运行调试代码段
如果您发现自己反复在控制台中运行相同的调试代码,不妨考虑使用代码段。 代码段是您在 DevTools 中编写、存储和运行的可执行脚本。
如需了解详情,请参阅从任何页面运行代码段。
监控自定义 JavaScript 表达式的值
使用“监视”窗格监控自定义表达式的值。您可以监视任何有效的 JavaScript 表达式。
- 点击添加表达式图标 以创建新的监视表达式。
- 点击刷新图标 可刷新所有现有表达式的值。在单步调试代码时,值会自动刷新。
- 将光标悬停在表达式上,然后点击删除表达式图标 将其删除。
检查和修改脚本
当您在网页窗格中打开脚本时,DevTools 会在编辑器窗格中显示其内容。在 Editor(编辑器)窗格中,您可以浏览和修改代码。
此外,您还可以在本地替换内容,或者创建工作区,并将您在 DevTools 中进行的更改直接保存到本地来源。
使缩减后的文件可读
默认情况下,Sources 面板会以美观的格式输出缩减过大小的文件。美化输出时,编辑器可能会将单行长代码显示为多行代码,并使用 -
表示代码是行续接。
如需查看缩减后的文件在加载时的状态,请点击 Editor 左下角的 { }
。
收起代码块
如需收起代码块,请将光标悬停在左侧列中的行号上,然后点击 Collapse(收起)。
如需展开代码块,请点击代码块旁边的 {...}
。
如需配置此行为,请依次选择 设置 > 偏好设置 > 来源。
修改脚本
修复 bug 时,您通常需要测试对 JavaScript 代码所做的某些更改。您无需在外部浏览器中进行更改,然后重新加载页面。您可以在开发者工具中修改脚本。
如需修改脚本,请执行以下操作:
- 在 Sources 面板的 Editor 窗格中打开该文件。
- 在编辑器窗格中进行更改。
按 Command+S (Mac) 或 Ctrl+S (Windows、Linux) 进行保存。开发者工具会将整个 JS 文件补丁到 Chrome 的 JavaScript 引擎中。
上图中的编辑器窗格用蓝色勾勒。
实时修改暂停的函数
在执行暂停期间,您可以修改当前函数并实时应用更改,但存在以下限制:
- 您只能修改调用堆栈中的最顶层函数。
- 堆栈更深层级不得对同一函数进行递归调用。
如需实时修改函数,请执行以下操作:
请观看下面的视频,了解此工作流程。
在此示例中,addend1
和 addend2
变量的 string
类型最初不正确。因此,系统会串联字符串,而不是对数字进行相加。为解决此问题,我们在实时编辑期间添加了 parseInt()
函数。
在脚本中搜索和替换文本
如需在脚本中搜索文本,请执行以下操作:
- 在 Sources 面板的 Editor 窗格中打开该文件。
- 如需打开内置搜索栏,请按 Command+F (Mac) 或 Ctrl+F (Windows、Linux)。
- 在该栏中,输入您的查询。
您也可以:
- 点击 Match Case(区分大小写)可使查询区分大小写。
- 点击 Use Regular Expression(使用正则表达式),以使用 RegEx 表达式进行搜索。
- 按 Enter 键。如需跳转到上一个或下一个搜索结果,请按向上或向下按钮。
如需替换找到的文字,请执行以下操作:
- 在搜索栏中,点击 Replace 按钮。
- 输入要替换的文字,然后点击替换或全部替换。