☰
现代 JavaScript 教程:用 Chrome DevTools 一步步调试浏览器中的 JavaScript
2026/10/6 2:01:31 网站建设 项目流程
  • 文档
  • 教程
  • 前端

【免费下载链接】zh.javascript.info

现代 JavaScript 教程(The Modern JavaScript Tutorial),以最新的 ECMAScript 规范为基准,通过简单但足够详细的内容,为你讲解从基础到高阶的 JavaScript 相关知识。

项目地址:https://gitcode.com/gh_mirrors/zh/zh.javascript.info
点击查看免费下载

调试(Debugging)是指在一个脚本中找出并修复错误的过程,它是每个前端开发者必须掌握的核心技能。本文基于 zh.javascript.info(现代 JavaScript 教程)仓库中的「代码质量 · 在浏览器中调试」章节展开,结合仓库自带的 调试示例页 与 hello.js 源码,系统讲解如何使用 Chrome(谷歌浏览器)开发者工具:从打开 Sources 面板、设置断点、使用debugger命令暂停脚本,到跟踪执行、检查变量与调用栈,再到用console.log记录日志。学完本章,你将能够独立完成脚本的断点调试、定位逻辑错误,并理解调试器背后「暂停—观察—步进」的核心工作流。

调试是什么,为什么需要调试工具

在编写更复杂的代码之前,先聊聊调试。所有现代浏览器和大多数其他环境都支持调试工具——即开发者工具中的一个特殊用户界面,它让调试变得更加容易。它允许我们一步步地跟踪代码,随时查看当前实际运行的情况,而不是靠猜测或盲目地往代码里塞输出语句。

本教程以 Chrome 为例展开讲解,因为它拥有足够多的功能;其他大部分浏览器(Firefox、Edge、Safari 等)的开发者工具功能与它也基本类似,掌握 Chrome 的操作后可以快速迁移。仓库中该章节位于 1-js/03-code-quality/01-debugging-chrome/article.md,属于「代码质量」篇(见 章节索引)的第一课,目的是在深入学习编码实践之前先解决「如何发现并定位错误」的问题。

准备调试示例:仓库自带的可运行页面

本仓库为该章节准备了两个配套文件,可以直接在浏览器中打开演练:

  • 示例页面 index.html:页面通过<script src="hello.js"></script>引入脚本,并在页面加载时调用hello("John");
  • 示例脚本 hello.js:包含两个函数hello()与say(),它们会依次被调用。

index.html的核心结构如下:

<!DOCTYPE HTML> <html> <body> <script src="hello.js"></script> An example for debugging. <script> hello("John"); </script> </body> </html>

hello.js的全部源码如下(注意行号,后面的断点设置会精确到行):

function hello(name) { let phrase = `Hello, ${name}!`; say(phrase); } function say(phrase) { alert(`** ${phrase} **`); }

调用链非常简单:页面加载 →hello("John")被调用 → 构造phrase字符串 → 调用say(phrase)→say弹出alert对话框。这个极简的例子足以演示断点、步进与变量检查等全部核心操作,是后面所有调试练习的载体。

打开开发者工具:Sources(资源)面板

在 Chrome 中打开上面的示例页面后,按下快捷键:

  • Windows / Linux:F12
  • Mac:Cmd+Opt+I

即可打开开发者工具,然后选择Sources(资源)面板。首次打开时,界面大致如下(不同 Chrome 版本可能略有差异,但面板位置通常很明显):

界面顶部的切换按钮(Toggle)可以打开/关闭左侧的文件列表选项卡。在文件预览树中点击并选择hello.js,Sources 面板会呈现出三个主要区域:

  1. 文件导航(File Navigator):列出依附于当前页面的所有文件,包括 HTML、JavaScript、CSS 以及图片等资源,Chrome 扩展程序也会显示在这里;
  2. 代码编辑(Code Editor):展示当前选中文件的源码,可直接阅读,也可以在断点处高亮当前执行位置;
  3. JavaScript 调试(JavaScript Debugging):用于调试的区域,包含断点列表、变量观察、调用栈、作用域等工具,我们马上会逐一探索。

如果觉得左侧文件列表占空间,可以再次点击切换按钮将其隐藏,为代码编辑区腾出更多空间。

控制台(Console):随时执行表达式

在 Sources 面板按下Esc键,底部会滑出一个控制台(Console)。在这里输入命令并按Enter即可立即执行,执行结果会显示在下方。

例如:

  • 输入1+2并回车,会返回3;
  • 输入hello("debugger")并回车,函数调用执行完毕但没有任何返回值,所以结果是undefined。

控制台是调试过程中最常用的辅助工具之一:当脚本在断点处暂停时,你可以在控制台里直接查看或修改当前作用域内的变量、调用函数,验证假设后继续执行,从而快速缩小问题范围。

断点(Breakpoints):让调试器自动暂停

断点(breakpoint)是调试器会自动暂停 JavaScript 执行的位置。当代码在断点处暂停时,我们可以检查当前变量、在控制台执行命令等——换句话说,我们可以开始「调试」它。

设置断点

继续使用hello.js:

  1. 在代码编辑区中,点击第 4 行的行号数字(say(phrase);那一行,注意是点击行号本身,不是点击代码);
  2. 同样地,在第 8 行的行号上再点击一下(alert(...)那一行)。

设置完成后,第 4 行和第 8 行的行号左侧会显示断点标记,效果如下图(蓝色标记处即断点位置):

管理断点

右侧的「断点列表」面板会汇总所有文件中设置的断点,当项目中有多个文件、多个断点时尤为有用:

  • 快速跳转:点击右侧面板中的某个断点,可直接跳到源码中对应的位置;
  • 临时禁用:取消选中某个断点前的复选框,即可临时禁用该断点(断点仍在列表中,但不会触发);
  • 删除断点:右键单击断点并选择移除,可彻底删除;
  • 等等。

条件断点

在行号上右键单击,可以创建一个条件(conditional)断点:只有你提供的表达式为真时,断点才会触发暂停。

例如:在一个循环中,只有当变量 `i` 等于某个特定值时(如 `i === 5`),或者在某个参数为特定值时(如 `name === "admin"`)才暂停执行。这可以避免手动多次点击「恢复」来跳过无关迭代,非常适合在特定变量值或特定参数出现时进行定点排查。

"debugger" 命令:在代码中直接指定暂停点

除了在开发者工具里点击行号,我们还可以直接在源码中使用debugger命令来暂停代码,例如把hello.js修改为:

function hello(name) { let phrase = `Hello, ${name}!`; debugger; // <-- 调试器会在这里停止 say(phrase); }

当 JavaScript 引擎执行到debugger语句时,如果开发者工具处于打开状态,执行会立即暂停;如果开发者工具没有打开,浏览器会直接忽略该语句,不影响正常运行。因此,debugger命令非常适合在开发阶段临时埋点:无需在 UI 上翻找行号,代码即调试点,逻辑一目了然。调试完成后再删除或注释掉即可。

暂停并查看:Watch、Call Stack 与 Scope

在示例中,hello()函数是在页面加载期间被调用的,因此激活调试器最简单的方式是——在设置好断点后重新加载页面:按下F5(Windows / Linux)或Cmd+R(Mac)。

页面重新加载后,程序会在第 4 行的断点处暂停执行,当前行会被高亮,同时编辑器上方会出现「暂停」状态栏:

暂停后,打开右侧的信息下拉列表(箭头指示的位置),这里有三个核心工具面板,用于查看当前的代码状态:

1. Watch(察看)—— 显示任意表达式的当前值

点击加号+并输入一个表达式(例如变量名、1 + 2、name.toUpperCase()等),调试器会显示它的当前值,并在执行过程中自动重新计算。当我们需要持续观察某个关键变量在多次步进中的变化时,Watch 是最直接的方案。

2. Call Stack(调用栈)—— 显示嵌套的调用链

此时调试器正停在hello()的调用链中:hello()由index.html中的一个脚本调用,由于该调用发生在全局脚本(不在任何函数内),调用栈中显示为"anonymous"(匿名)。

如果点击调用栈中的某一项,调试器会跳到对应的代码位置,并且可以查看该层栈帧的所有变量。在多层函数嵌套调用时,调用栈能清楚回答「我是被谁调进来的」「上一层是什么状态」这两个关键问题。

3. Scope(作用域)—— 显示当前的变量

  • Local(局部):显示当前函数中的变量;对应变量在源代码中也会以高亮形式标出当前值(例如本例中可以看到name = "John"、phrase = "Hello, John!");
  • Global(全局):显示全局变量(不在任何函数中的变量);
  • 此外还有this关键字的值——本教程此阶段尚未讲到this,后续章节会专门学习。

暂停时,这三块面板配合控制台,足以对当前执行环境做一次完整的「体检」。

跟踪执行:逐条语句地观察脚本

暂停之后,我们就可以开始跟踪(stepping)脚本了。右侧面板顶部有一组跟踪按钮,作用如下:

按钮名称行为快捷键
恢复(Resume)继续执行,直到下一个断点(若无其他断点则直接运行完)F8
下一步(Step)运行下一条(当前行)指令;若下一条是函数调用,会进入函数内部并在其第一行暂停F9
跨步(Step over)运行下一条指令,但不会进入函数内部,函数调用会「不可见地」整体执行完F10
步入(Step into)与「下一步」类似,但遇到异步函数调用时会进入代码内部并等待F11
步出(Step out)继续执行当前函数内的剩余代码,暂停在调用当前函数的下一行Shift+F11

(注:表格中的图标在仓库中由 largeIcons.svg 提供,并由 head.html 中的 CSS 类渲染,界面截图见 chrome-sources-debugger-trace-1.svg。)

各按钮的详细行为如下。

恢复(Resume)——F8

继续执行。如果没有其他的断点,程序就会继续跑完,调试器不再控制它。

在示例中:点击「恢复」后,执行会从第 4 行的say(phrase)调用继续,随后命中say()函数内部的第 8 行断点并再次暂停。此时再看右侧的Call Stack,会发现调用信息增加了一层——我们现在已经位于say()内部。

下一步(Step)——F9

运行下一条(即当前行)指令。以示例为例,如果当前停在say(phrase)这一行,点击「下一步」会进入say()函数内部;如果当前在say()内,点击它会执行alert语句(屏幕上会弹出提示框)。一次接一次地点击此按钮,整个脚本的所有语句会被逐个执行。

跨步(Step over)——F10

跟上一条「下一步」类似,但如果下一条语句是函数调用则表现不同。这里的「函数」指的是我们自己写的函数(而不是alert这类内建函数)。

  • 「下一步」会进入嵌套函数调用,并在其第一行暂停;
  • 「跨步」则对我们不可见地整体执行嵌套函数调用,跳过函数内部,然后在函数调用返回后立即暂停。

如果我们对该函数的内部执行不感兴趣,用「跨步」跳过它会非常高效。

步入(Step into)——F11

和「下一步」类似,但在异步函数调用的情况下表现不同。如果你刚开始学 JavaScript,可以先忽略这个差异——因为我们目前还没有用到异步调用。之后只需记住:

  • 「下一步」会忽略异步行为,例如setTimeout(计划中的函数调用,会过一段时间再执行);
  • 「步入」会进入异步代码并等待(如果需要)。

步出(Step out)——Shift+F11

继续执行当前函数内的剩余代码,并暂停在调用当前函数的下一行代码处。当我们不小心用「下一步」进入了一个嵌套调用,但对该函数内部并不感兴趣时,用它一步回到外层调用点,非常方便。

两个批量开关

右侧面板顶部还有两个常用的开关按钮:

  • 启用/禁用所有断点:批量地打开或关闭全部断点。这个按钮不会影响程序的执行,只是一个断点的总开关,适合临时挂起整套断点策略;
  • 出错时自动暂停:启用后,只要开发者工具是打开的,任何脚本执行错误都会导致脚本自动暂停。随后就可以在调试器中分析变量、查看上下文,弄清楚到底哪里出错、出错时的状态是什么。因此,如果脚本因为错误「挂掉」了,可以打开调试器、启用这个选项、重载页面,一步步观察错误发生前的现场。

Continue to here(执行到此处)

在代码中的任意一行上右键单击,弹出的关联菜单(context menu)里有一个非常实用的选项 ——"Continue to here":让程序继续执行直到这一行再暂停。当你想要向前推进很多步、但又不愿专门去设置一个断点时,它是最快捷的选择。

日志记录:用 console.log 留下运行痕迹

调试器并不是观察代码运行的唯一手段。想要向控制台输出信息,可以使用console.log函数。例如,将0到4的值输出到控制台:

// 打开控制台来查看 for (let i = 0; i < 5; i++) { console.log("value", i); }

普通用户看不到这些输出——它们只出现在控制台里。查看方式有两种:

  1. 打开开发者工具中的Console(控制台)选项卡;
  2. 在任意其他选项卡中按下Esc键,在下方打开控制台。

如果在代码中留有足够的日志记录,那么即使不借助调试器,我们也能从日志中还原「刚刚发生了什么」。日志适合快速粗排,调试器适合精确定位,两者互为补充。需要提醒的是:上线前的代码里应清理掉不必要的调试日志,避免噪音与敏感信息泄露。

小结:三种暂停脚本的方式与调试工作流

综合全文,共有3 种方式可以让脚本暂停:

  1. 断点:在开发者工具中点击行号设置,最常用的方式;
  2. debugger语句:直接在源码中写入暂停指令,代码即断点;
  3. error(脚本错误):当开发者工具打开且「出错时自动暂停」开关开启时,任何执行错误都会导致脚本自动暂停。

无论通过哪种方式暂停,之后都可以进行完整的调试动作:检查变量、查看调用栈、跟踪(步进)代码来定位执行出错的位置。这正是浏览器调试的核心工作流:暂停 → 观察 → 步进 → 修复 → 重载验证。

开发者工具中的功能远不止本文介绍的这些。完整的手册可以查阅 Chrome DevTools 官方文档(本文成文时的浏览器版本请以实际界面为准);本章的内容已经足够让你上手代码调试。后续随着浏览器相关的开发越来越多,强烈建议进一步探索开发者工具的高级功能。最后一个小建议:大胆点击开发者工具中的各个区域,看看会显示什么——这可能是学习开发者工具最快的方式,也别忘了右键单击和关联菜单里隐藏的各种快捷能力。

  • 文档
  • 教程
  • 前端

【免费下载链接】zh.javascript.info

现代 JavaScript 教程(The Modern JavaScript Tutorial),以最新的 ECMAScript 规范为基准,通过简单但足够详细的内容,为你讲解从基础到高阶的 JavaScript 相关知识。

项目地址:https://gitcode.com/gh_mirrors/zh/zh.javascript.info
点击查看免费下载
上一篇:Auxílio RS SDK开发指南:构建第三方集成
下一篇:OpenClaw × Mem0 记忆整合机制详解:memory-dream 技能的 Dream 协议、触发门槛与源码实现

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询