原文:Debugging Javascript Like a Projavascript
当您的代码没有按照预期执行的时候,您是否还在用 console.log
来进行调试?若是是,那这篇文章就是为您准备的。前端
我写这篇文章的目的是让您了解 Chrome 开发工具提供的高效工具,让您能够更好、更快地调试 Javascript 代码。java
本文主要讲述如下几点内容:node
当代码出现 bug 或没有按照预期执行时,咱们一般会查看开发者工具中的 Sources
选项卡,接下来咱们将经过不一样场景来深刻了解这个功能模块。web
在阅读本文以前,您可能习惯于使用控制台打印某个值来调试代码。但我但愿向您介绍一种更高效的方法,一种能更深刻代码中的方法:断点。chrome
设置断点一般是调试过程的第一步。虽然目前大多数浏览器中的内置开发工具,都容许您调试正在浏览的页面,中止在特定代码行上或者在特定语句上执行代码,但在本文中,咱们将主要讲解 Chrome 开发者工具。数组
一般,您可能但愿中止执行代码,以便您能够逐行地查看特定的上下文。浏览器
一旦代码在断点处中止,咱们就能够经过访问做用域,查看调用堆栈,甚至在运行时更改代码来进行调试。markdown
因为使用哪一种前端技术对调试来讲并不重要,为了更方便地向您解释断点,我将调试用于培训的一个 Angular 项目。异步
Sources
选项卡小提示:在 Mac 上,使用快捷键 ⌘ + O
能够打开文件选择器,您能够在其中找到您须要调试的文件。在 Windows 上,可使用 CTRL + O
如上图所示,咱们能够在一行代码上更深刻地设置断点,例如在一行代码里的不一样语句。
咱们设置了3个断点:
priceReceived
函数执行以前中止priceReceived
被调用后当即中止,所以咱们也能够检查箭头函数的返回值当调用箭头函数时,执行中止,右侧面板 Scope
将显示当前的上下文,并容许咱们访问全部咱们想查看的值。
以下图所示,咱们能够看到变量 price
的值 。
在下图中,一旦 priceReceived
执行,第三个断点就会被使用。
在右侧面板中您可使用 Return value
查看匿名函数的返回值。
场景:您在代码中设置了一堆断点。
在调试时,屡次刷新页面是很常见的操做。
您当前正在调试的代码可能有各类断点,有时候甚至会达到几百个。这几百个断点可能会浪费您大量的时间。
在这种状况下,能够暂时暂停全部断点的执行,您能够经过切换下图中的图标来操做:
场景:您的代码执行产生了错误,但您不想设置断点,由于您不知道什么时候会抛出错误。
在您的代码中抛出错误,这样就能够查看代码出现了什么问题。
顾名思义,条件断点就是仅在条件为真时触发的断点。
例如,在上面的示例中,用户能够在文本区域中输入非数值。因为 JS 的兼容性只会显示 NaN 而不是抛出错误。
场景:您的代码比上面的代码更复杂,而且没法肯定什么时候出现 NaN 。
固然,您能够设置一个断点,但复现错误并不容易,可能最终花费半小时来执行代码。在这种状况下,您可使用条件断点,并仅在出现 NaN 时中止执行代码。
以下图:
为了充分利用 Dev Tools,值得花一点时间学习开发工具如何帮助咱们快速单步执行代码,而无需在每一行设置断点。
使用 Dev Tools 中的 navigator 能够顺序逐行执行代码。
我将在下面介绍 Step over next function call
与 Step
的不一样。在调试异步代码时,点击 Step
按钮将按时间顺序移动到下一行。
Step over next function call
按钮也会顺序执行代码,但不会进入函数调用。也就是说,函数调用将被跳过,除非您在函数中设置了断点,不然调试器将不会在该函数中中止。
若是您仔细观察上图,会发现 multiplyBy 和 renderToDOM 这两个方法执行时没有像 Step
那样进入函数内部。
自 Chrome 68 以来,Step Into Next function call
按钮的做用发生了改变。它相似于上面提到的 Step
。不一样之处在于,当进入异步代码时,它将中止在异步代码中,而不是按时间顺序运行的代码
如上图所示:若是按时间顺序,第32行应该已经运行,但事实并不是如此。调试器在等待2秒后才移动到第29行
假设调试代码时,您不想进入某个函数的内部,Step Out of function call
容许您退出函数并在函数调用后的下一行中止。
上图中发生了什么?
renderToDOM
renderToDOM
函数的剩余部分有时,在全局范围内存储某些值(例如组件类,大型数组或复杂对象)会很是有用。
例如,当您想要传入不一样的参数调到某个组件的方法时,在调试过程当中将这些参数添加到全局范围能够节省大量时间。
在上图中,我将数组 [previous, current]
存为全局变量。开发者工具会自动分配一个名为 temp{n}
的变量,n 基于先前保存的变量的数目。
如上图所示,变量被命名temp2,您能够在控制台中使用它,由于它如今已经是一个全局变量了!
即时输出是 Chrome 68 中发布的一项功能,开发工具容许您在输入代码时在控制台中显示执行的结果。
若是您仔细观察上图会发现,当我将保存的变量映射到字符串数组时,我没有按下 Enter 键,但结果当即显示在下一行。
查看调用堆栈是开发者工具提供的最有用的工具之一:您不只能够在调用它们的函数中来回跳转,还能够在每一个步骤检查它们的做用域。
假设咱们有一个简单页面和一个输入数字的脚本,并在页面上呈现数字乘以10.咱们将调用两个函数:一个用来作乘法,一个用来将结果渲染到页面中。
如上图所示,只需单击 “Call Stack” 窗格中的函数名称,咱们就能够浏览它们的做用域。
若是您仔细观察会发现,每次咱们从一个函数调用跳到另外一个函数调用时,做用域都会保留,咱们能够在这里对每一步进行分析!
Blackboxing 脚本将经过从堆栈中排除特定的脚本或某些匹配模式的脚原本过滤调用堆栈。
例如,若是我有99%的时间只调试 userland 中的代码感兴趣,我能够在 Blackbox 中添加一个模式,将 node_modules 文件夹下的全部脚本过滤掉。
要经过 Blackbox 过滤一个脚本,有两种方法:
Sources
选项卡中的 JS 脚本,而后单击“Blackbox Script”Add Pattern...
并输入您想要加入 Blackbox 的正则,在您想要过滤大量脚本时颇有用。经过监视表达式,您能够定义一些 Javascript 语句,在开发者工具运行显示这些语句的结果。这是一个特别有趣的工具,由于您能够写任何您想要的虚拟状况,只要它是一个有效的Javascript表达式。
例如,您能够编写一个结果始终为 true 的表达式,当表达式结果为 false 时 ,您就能够发现当前的运行状态存在问题。
有一个须要注意问题:
浏览器开发者工具是调试复杂代码的利器。有时您可能须要比 console.log
更进一步的操做,上面提到的功能将提供深刻代码底层的调试体验。这些工具须要一些练习才能彻底掌握,因此若是您对部分功能还不熟悉,请不要放弃,继续坚持使用它们。
如下是一些资料,能够帮助您彻底掌握开发工具提供的全部功能:
欢迎转载,记得注明做者和来源哦~~