使用条件断点进行更好的调试

发布于:2021-02-14 00:00:06

0

165

0

条件断点 Firebug web开发 调试

我喜欢条件断点。真的!它们是我最喜欢的调试工具。

当我开始从事web开发时,“调试”对我来说意味着创建一个<pre id='log'></pre>,并在其内容中添加字符串作为日志。但是一旦Firebug出现,然后浏览器开始使用自己的开发工具——它就像从滑板升级到私人飞机。断点、监视、调用堆栈、分析器、网络活动监视器——它们都很有用,我不想失去它们中的任何一个。

但是条件断点是我最喜欢的,而且它甚至不接近。下面是我如何使用它们:

只有在特定条件下才会破坏

最明显的例子是到处都有文档记录的例子:创建一个断点,只在特定表达式的计算结果为true时暂停执行。

屏幕截图显示了设置条件断点的示例。

当我试图在经常运行的代码段中跟踪某些奇怪的行为,但只有在出现特定的数据组合时才会破坏该代码段的行为时,以这种方式使用条件断点是很好的。普通的断点每次都暂停执行,调试工作非常繁琐,但是条件断点只允许在有正确数据时暂停,这样您就可以停下来四处查看。

但这是很普通的用法。老实说,这可能是我使用它们最不常见的方式。条件断点就是一把手术刀。它们是猴子修补匠的梦想。

将变量导出到全局作用域

您是否曾经遇到过这样的情况:您想要控制台访问在函数中局部定义的变量,但从函数外部的执行上下文?这一直发生在我身上;我想让我的应用程序加载并运行,直到达到空闲状态,然后能够检查,比如,锁定在闭包中的某个对象的属性或方法。条件断点的拯救!

屏幕截图显示了一个条件断点,该断点为窗口分配了局部变量。

这里的主要技巧是使用低逗号运算符,以确保该赋值不会评估为真,因为这会导致断点暂停执行。取而代之的是,断点表达式求值,false并且应用程序一直沿其运行并一直运行到空闲为止,然后您只需键入其名称即可检查控制台中与您内心内容有关的值。

注意:我习惯于这样做,window.varName而不仅仅是varName这样做,所以我不会意外地修改相对于断点位置存在于外部作用域中的变量。

Protip:在启用了ES2015 +的浏览器中,使用简写属性名称快速导出一系列变量:window.dealyBob = {var1, var2, otherVar}, false

以这种方式使用逗号操作符是触发条件断点的关键。

在不编辑代码的情况下添加日志

有条件断点的最常见用例是日志记录。我知道在专业开发人员中打趣console.log驱动开发是很普遍的,但是能够无需重新构建甚至不重新加载就能够检测代码,实时观察一切,并获得详细的诊断输出,这真是太棒了。

屏幕截图显示了一个条件断点,该断点执行console.log()并在函数内部本地保存了一些数据

这样做的奇妙之处在于,开发工具将保存断点与相关文件的关联(至少在Chrome中,这些天我通常最常在其中工作),因此下次我仍在使用它们在另一个会话中加载该应用程序,而无需我真正保存对我的应用程序代码的任何更改!这给了我一种纯粹面向浏览器的运行时面向方面的日志记录系统。如何分离关注点?

修改资料

假设您有一个错误,即复制要加载特定的数据组合,并且要恢复到该状态,您首先要执行许多繁琐的步骤。不再!作为一个敏锐的读者,我相信您之前已经注意到,如果可以window在条件断点表达式中修改属性以创建新的全局变量,那么没有什么可以阻止您修改其他内容。

屏幕截图显示了一些代码,这些代码为函数内部本地保存的对象的属性分配值

因此,继续将一堆JSON粘贴到条件断点中,并将其分配给所需的任何变量。繁荣!告别繁琐的复制。

提示:逗号运算符使您可以将两个以上的语句链接在一起,因此,如果要进行一整套分配,请继续说:(var1 = x; var2 = y; var3 = z), console.log('overriding with', x, y, z), false

相关的Protip:不要忘记您可以从控制台在任何全局对象上设置值。如果您有特别大的对象用作替代,或者如果您想更改条件断点将使用的数据而不必修改实际断点,则将您带到控制台并说window.bigOverrideObject = {pasteYourObjectHere},然后在条件断点表达式中,var1 = window.bigOverrideObject, false

注入和测试新代码

您是有见识的读者,您可能已经意识到条件断点表达式只是在放置它们的作用域和上下文中运行的JavaScript代码。如果您可以在条件断点处进行分配或写入控制台,为什么不使用它来测试新的应用程序代码?

屏幕截图显示了条件断点,该断点计算文档字数并将其显示在UI中

在任意位置插入一个条件断点,然后运行所需的任何内容!有一些限制-例如,您不能return从当前函数直接在断点表达式中进行操作-但在大多数情况下,您可以执行应用所需的任何转换或计算。

这就是猴子补丁方面的来龙去脉:您可以结合所有这些技术,并使用条件断点来覆盖整个函数,即使它们在闭包内部也是如此。检查:

屏幕截图显示了覆盖整个内部函数的条件断点

提示:您的开发工具显然不会修改已部署的应用程序代码,因此这是一种在不进行整个构建/部署周期的情况下尝试在生产系统中进行操作的好方法。小心不要以使它们最终破坏您的生产数据的方式进行调整!

结论

我喜欢条件断点。现在我希望你也这样做!