调试是程序员活动中的核心技能之一。
有时我们做了最好的工作,但程序却不能正常工作,例如,它崩溃了,它只是很慢,或者它打印了错误的信息。
当你写的程序表现得不像你期望的那样时,你会怎么做?
你开始调试它。
弄清错误所在
第一步总是要看看正在发生什么,并试图确定问题来自哪里。是环境中的问题吗?是你给程序的输入的问题吗?是由于内存使用量太大导致的一次性崩溃?还是在你每次运行时都会出现这种情况?
这些都是在找出问题时开始向正确方向前进的关键信息。
一旦你对错误的来源有了一定的了解,你就可以开始检查代码的那个特定部分。
阅读代码
最简单的调试方法,至少在工具方面,是通过阅读你写的代码。大声读。从我们自己的声音中听到一些神奇的东西,这在你默读时是不会发生的。
很多时候,我就是通过这种方式发现问题的。
使用控制台
如果阅读代码没有发现任何问题,那么下一个合乎逻辑的步骤就是开始在你的代码中添加几行可以说明问题的内容。
在JavaScript的前端代码中,你经常要做的是使用alert() 和console.log (以及它的酷朋友)。
考虑一下这一行。
const a = calculateA()
const b = calculateB()
const result = a + b
不知何故,结果不能正确计算,所以你可以在计算结果之前先加入alert(a) 和alert(b) ,浏览器在执行代码时就会打开两个警报面板。
const a = calculateA()
const b = calculateB()
alert(a)
alert(b)
const result = a + b
如果你传递给alert() 的是一个字符串或一个数字,这就可以正常工作。一旦你有一个数组或一个对象,事情就开始变得太复杂了,alert() ,你可以使用控制台API。从console.log() 开始。
const a = calculateA()
const b = calculateB()
console.log(a)
console.log(b)
const result = a + b
该值被打印在浏览器开发工具的JavaScript控制台中。为了方便起见,我在这里解释Chrome开发工具中的调试,但一般的概念适用于所有的浏览器,只是在支持的功能方面有一些区别。
console.log() 调用的结果会打印到JavaScript控制台。这是每个浏览器或多或少都有的一个工具。

这个工具非常强大,可以让你打印复杂的对象或数组,你可以检查它们的每个属性。
在Console API一文中,你可以看到所有的选项和使用它的细节,所以我不在这里解释所有的细节。
调试器
调试器是浏览器开发工具中最强大的工具,它位于源面板中。

屏幕的顶端部分显示了文件导航器。
你可以选择任何文件并在右边检查它。这对于设置断点是非常重要的,我们将在后面看到。
下面的部分是实际的调试器。
断点
当浏览器加载一个页面时,JavaScript代码被执行,直到遇到一个断点。
在这一点上,执行被停止,你可以检查所有关于你的运行程序。
你可以检查变量值,并逐行恢复程序的执行。
但首先,什么是断点?简单来说,断点就是在你的代码中加入一条breakpoint 指令。当浏览器遇到它时,它就会停止。
这是开发时的一个好选择。另一个选择是在 "源 "面板中打开文件,点击你想添加断点的那一行的数字。

再次点击该断点会将其删除。
添加断点后,你可以重新加载页面,当代码找到断点时就会停止在该执行点。
在你添加断点时,你可以在断点面板上看到form.js ,在第7 行有断点。你可以在那里看到你所有的断点,并暂时禁用它们。
也有其他类型的断点。
- XHR/fetch断点:当任何网络请求被发送时被触发。
- DOM断点:当一个DOM元素发生变化时被触发
- 事件监听器断点:当某些事件发生时被触发,比如鼠标点击。

范围
在这个例子中,我在一个事件监听器中设置了一个断点,所以我必须提交一个表单来触发它。

现在,所有在范围内的变量都被打印出来,并附有各自的值。你可以通过双击这些变量来编辑它们。
观察变量和表达式
在范围面板的右边有一个观察面板。
它有一个+ 按钮,你可以用它来添加任何表达式。例如,添加name 将打印name 变量值,在这个例子中Flavio 。你可以添加name.toUpperCase() ,它将打印FLAVIO 。

恢复执行
现在脚本都被停止了,因为断点停止了执行。
在 "暂停执行断点 "的横幅上方有一组按钮,可以让你改变这一状态。
第一个是蓝色的。点击它可以恢复正常的脚本执行。
第二个按钮是跨步,它恢复执行到下一行,然后再停止。
下一个按钮执行步入操作:进入正在执行的函数,让你去了解它的细节。
step out则相反:回到调用这个函数的外部函数。
这些是在调试期间控制流程的主要方法。
编辑脚本
在这个devtools屏幕上,你可以编辑任何脚本,也可以在脚本停止执行时编辑。只要编辑文件,然后按Mac上的cmd-S或Windows/Linux上的ctrl-S。
当然,除非你在本地工作并在devtools中设置了工作空间,否则所做的修改不会持久化到磁盘上,这是一个更高级的话题。
检查调用堆栈
调用堆栈对于查看你深入到JavaScript代码的多少个函数层是非常好的。它也可以让你通过点击每个函数名称在堆栈中向上移动。

黑盒脚本
很多时候,你和一些你不想 "进入 "的库一起工作,你信任他们,你不想在调用栈中看到他们的代码,例如。就像上面提到的validator.min.js ,我用它来验证电子邮件。
我相信它做得很好,所以我可以在调用堆栈中右键单击它,然后按黑盒脚本。从此以后,就不可能再踏入这个脚本代码了,你愉快地只在自己的应用代码上工作。
由于Node.js是建立在Chromev8的同一引擎上,你可以将2者联系起来,并使用Chrome DevTools来检查Node.js应用程序的执行情况。
打开你的终端并运行

然后在Chrome中输入这个URL。about://inspect.

点击Node目标旁边的Open dedicated DevTools for Node链接,你就可以在浏览器DevTools中访问Node.js了。

请确保你点击这个链接,而不是下面的检查链接,因为当我们重新启动Node.js实例时,该工具会自动重新连接到Node.js实例--非常方便!