停止使用 `console.log`,开始使用你的 DevTools🛠️
很多情况下,我们都希望能够快速查看代码中的问题,而无需费力修改源代码,然后再次推送修改,无论我们使用的是本地环境还是生产环境。大多数人会先console.log
在整个代码库中编写语句,然后逐步查找错误发生的位置。对于初学者来说,如果可以访问源代码,这样做是可以的。但是,如果您不想浪费太多时间,或者您甚至无法访问源代码,该怎么办呢?
开发者工具
如今,所有主流浏览器都提供了开发者工具(又称 DevTools)。对于我们 Web 开发者来说,熟悉这些工具至关重要,不仅因为我们每天都会用它们来测试应用程序,查看部署后的效果,也因为我们希望在出现问题时能够高效地找到它们。
如果你熟悉 DevTools,那么 DevTools 就派上用场了。DevTools 功能丰富;请参阅我的文章《Chrome DevTools 能做到吗?》和《FireFox DevTools 能做到吗?》,了解其中的一些功能。不过,本文我们只关注调试体验。
漏洞
为了达成共识,我们需要修复一个 bug。我创建了这个 demo ,它将在Glitch中运行。在这个 demo 中,你选择一个日期,然后点击“计算年龄”按钮。它会计算你的年龄并显示在底部。
然而,存在一个错误,有时会导致计算出的年龄比实际年龄高一岁。我们将研究如何解决这个问题。
DevTools 的调试器
Chrome 和 Firefox 都包含调试器部分,我们将在本文中使用。我不会介绍 Edge,因为它与 Chrome 相同。
铬合金
Ctrl您可以在 Chrome 中使用+ Shift+(J在 Windows 上)或Ctrl+ Option+打开 DevTools J。
打开后,导航到“Sources”选项卡。您将在左侧看到一个文件导航窗格,您可以在其中检查页面使用的文件。然后,中间是编辑器窗格,您可以在导航窗格中点击文件,查看内容并在浏览器中进行本地编辑。最后,您将看到 JavaScript 调试窗格,其中包含一组稍后将要学习的功能。
💡 如果调整 DevTools 的大小,您可能会看到这些窗格位于不同的位置。
火狐
在 Firefox 中,您需要使用Windows 上的Ctrl++或++来打开 Web 开发人员工具。ShiftICtrlOptionI
打开后,点击“调试器”选项卡,它与你之前看到的非常相似。在左侧,你会看到导航窗格,旁边是编辑器窗格,左侧(或下方,取决于你打开的 DevTools 的宽度)是调试窗格。
设置断点
在调试时,一种常见的方法是console.log
在整个代码库中使用语句,但有时这种方法会被滥用。
const yo = document.querySelector('#yo');
function getAge() {
console.log('Getting the date of birth value');
const dateString = document.querySelector('#age').value;
console.log(`date of birth is ${dateString}`);
var today = new Date();
var birthDate = new Date(dateString);
var age = today.getFullYear() - birthDate.getFullYear();
console.log(`age is ${age}`);
var m = today.getMonth() - birthDate.getMonth();
console.log(`Birth month is ${m}`);
if (m < 0 || (m = 0 && today.getDate() < birthDate.getDate())) {
console.log('The birth month is negative or is zero, we need to reduce the age by one year');
age--;
console.log(`Real age is ${age}`);
}
yo.textContent = age;
}
然后你查看控制台,看看错误可能出在哪里。但这个过程非常缓慢,会严重影响你的工作效率。所以,让我们看看断点是如何帮助我们快速找到问题的。
console.log
与需要等待代码部署并检查控制台的语句相比,断点的优势在于它是实时的。除此之外,使用console.log
语句时,您需要明确指定期望的值,而断点调试器会显示所有值。
现在我们回过头来看看如何找到断点的位置。在某些情况下,你可能会觉得没问题,年龄有时是正确的,有时又不正确,这取决于月份。所以,你可以找到你的文件,并在条件if
所在的位置设置断点。
在其他一些情况下,代码库可能较大,或者您可能是团队新成员,那么遵循页面流程是有意义的。在我们的例子中,用户选择一个日期,然后点击计算年龄按钮。
背后的逻辑发生在点击事件中,对我们来说最好的办法是在点击事件监听器上设置一个断点。事件监听器断点就是为此设计的。
铬合金
在 Chrome 的调试页面中,点击“事件监听器断点”并展开该部分。然后找到“鼠标”类别并选择点击事件。
现在点击计算年龄按钮,DevTools 会在事件监听器执行时暂停。如果您使用的是 Glitch 之类的平台,可能需要点击“恢复脚本执行”按钮,但对于您自己的应用,无需执行此操作。当断点到达 HTML 中的按钮时,点击“单步执行函数”
,您将进入所需的
getAge
函数。单步执行所需的函数后,您可以点击“单步跳过”按钮或按 键,逐行执行F10。
火狐
您可以使用相同的方法在 Firefox 中启用鼠标单击事件监听器断点,只需展开调试器窗格中的事件监听器断点部分,然后展开鼠标并选择单击事件。
启用后,您可以按照我们之前描述的相同步骤操作。首先点击“计算年龄”按钮,调试器会在第一个函数调用处自动暂停。如果您使用 Glitch 或 CodePen 之类的平台,这可能不是您想要的效果,因此只需按下“继续”按钮,直到看到断点停在该
getAge
函数处。然后点击“单步执行” 按钮或按下进入函数内部。进入函数内部后,只需按下“单步跳过”按钮或按下 逐行执行即可。 F11
F11
行断点
行断点主要用于缩小 bug 可能存在的位置。在我们的例子中,当我们单步执行getAge
函数时,我们看到年龄是根据年份计算的,然后有一个 if 条件,如果月份小于当前月份减去出生月份,则将年龄减一。
因此,我们粗略地知道,如果在某些情况下年龄计算正确,而在其他情况下年龄计算错误一岁,那么我们就应该在 if 条件上设置行断点。
在 DevTools 中有两种方法可以执行此操作,一种是按照上面解释的事件监听器断点流程进行操作。但是,如果您事先知道文件名,则可以直接在编辑器窗格中打开文件并滚动浏览,直到到达所需的行。
到达那里后,只需点击行号,它就会在该行上显示一个“行断点” 图标,以便您知道断点设置的位置。只需再次点击即可移除断点。
现在,如果您点击计算年龄按钮,程序就会在 if 条件处停止。此部分在 Chrome 和 Firefox 中完全相同。
检查变量值
当您在 if 条件处停止时,如果您想查看变量的值,只需查看Chrome 中的调试器窗格的范围部分或Firefox 中的范围部分。
铬合金
火狐
发现漏洞
现在让我们看看错误在哪里以及如何修复它。如果你仔细查看 if 条件,你会发现其中有两个主要部分。第一部分是m < 0
检查月份是否小于零,第二部分是m = 0 && today.getDate() < birthDate.getDate()
检查月份是否为零且今天是否小于生日。
现在我们知道有人使用了等号而不是等号运算符,导致了这个 bug。所以让我们用 替换=
,===
然后按Ctrl+S保存更改。你可以保留断点或移除它,用一些日期测试一下,看看 bug 是否已修复。经过一些测试,我们知道 bug 已经修复了。现在是时候为这个函数编写一个测试了,这样你就不会再遇到同样的 bug 了😁。
控制台窗口
别忘了,你可以在浏览器的控制台窗口中执行表达式。也就是说,你可以直接在控制台中输入条件,看看它是否返回true
或false
。
还有什么?
您还可以使用许多其他断点,例如仅当您提供的条件为时才触发的条件断点true
、捕获和未捕获异常的断点以及当 URL 与您设置的子字符串匹配时触发的 XHR 断点。让我们尝试在中设置 XHR 断点,打开您的 DevTools,转到调试窗格并打开XHR 断点部分。在框中单击以添加一行,然后输入raw
并按Enter。现在刷新页面,您将看到发出请求时命中断点。现在您可以使用我们之前看到的相同技术来单步执行代码并设置类似的断点以进一步调试。
小渔获
需要注意的是,你需要确保正在调试的函数在作用域内,如果你使用 DevTools,这一点会比较棘手。为了使其正常工作,你需要在函数作用域内的某个位置设置一个行断点,然后触发该断点,并在debug()
代码仍暂停在行断点处时在 DevTools 控制台中调用该断点。
(function () {
function hello() {
console.log('hello');
}
function world() {
console.log(' world');
}
hello(yo); // This works.
world();
})();
debug(hello); // This doesn't work. hey() is out of scope.
概括
我们见识了 DevTools 的强大功能,以及它们在代码中查找和修复 bug 方面的强大能力。所以,别再用console.log
DevTools 了,赶紧去深入了解一下吧!祝你在家编程愉快 ❤️。