Debug JavaScript(调试、debugger)

前言


“磨刀不误砍柴工”。大家好👏,今天给大家简单介绍一个在浏览器中debugger代码的方法,同时给了一个小案例,结合实际讲解。最后简单阐述使用console.log调试代码和使用断点调试代码的一些个人见解。(大佬可绕路…)

第一步:重现错误


  1. 在浏览器的新 tab 页中,打开这个 demo
  2. Number 1中输入 2;
  3. Number 2中输入 3;
  4. 点击Add Number 1 and Number 2按钮,这时候按钮下方的标签显示 2 + 3 = 23。这个例子正确的结果是 5,而不是 23 。这就是我们要修复的错误。

Debug JavaScript(调试、debugger)

第二步:熟悉 Sources tab


打开浏览器开发者工具,将 tab 页切换到 Sources,这是今天的‘主角’,一直围绕它展开讲解。

Debug JavaScript(调试、debugger)

这里就简单介绍下 Sources 面板的 ui 样式,总共分为三大模块:

  • 模块一:文件导航区, 显示各种资源文件,包括 html,css,js,img 等文件;
  • 模块二:代码编辑区, 和文件导航区是联动的,点击文件导航区的某个资源文件,可在这里打开并编辑它;
  • 模块三:代码调试区, 在这里可以调试我们写的 JavaScript 代码;

第三步:设置 Breakpoints,暂停代码


首先分析一下产生这个错误结果的过程:在Number 1 中输入 2,然后在Number 2 中输入 3,点击 Add Number 1 and Number 2 按钮,之后出现的错误结果。注意 ,点击之后出现的。所以我们可以想到,在代码调试区中,Event Listener Breakpoints可以满足我们的需求:

    1. 打开代码调试区, 单击Event Listener Breakpoints以展开该部分。 它显示了一个可扩展事件类别列表,例如 AnimationClipboard。 在这里我们只用注意 Mouse 即可,其他的以后用到再了解;
    1. 点击 Mouse, 然后再点击 click 即可,这样只要一触发 click事件, 就会暂停代码;
      Debug JavaScript(调试、debugger)
    1. 断点已经设置好了,那现在点击Add Number 1 and Number 2按钮,此时代码编辑区会暂停在触发click事件的函数的可执行代码第一行:
    // function onClick() 
    if (inputsAreEmpty()) {
    

Event Listener Breakpoints只是众多设置断点中的其中一种,根据我们的需求,我可以设置其他类型的断点来暂停代码。

第四步:逐步(单步)执行代码


重点关注代码调试区中的顶部栏目(没有讲解到的序号功能之后再做详细介绍,其实鼠标放到序号出现的对应提示信息已经说的很清楚了)。

Debug JavaScript(调试、debugger)

在代码执行的过程中,代码未按顺序执行是产生错误结果的原因之一。逐步(单步)执行代码,就可以来排查是否是该原因造成的错误结果,它是一步一步执行代码的。(以下两种情况是并列的):

  • 点击顶部栏目中的序号3(Step into next function call),代码行会进入到调用函数的可执行第一行
// function inputsAreEmpty() 
if (getNumber1() === '' || getNumber2() === '') {
  • 点击顶部栏目中的序号2(Step over next function call),inputsAreEmpty()这个函数不会执行,相当于if (inputsAreEmpty())被评估为 false。所以代码行会停留在
updateLabel();

这就是单步执行代码的基本思想。如果您查看 get-started.js 中的代码,您会发现错误可能出在 updateLabel() 函数中的某处。您可以使用另一种类型的断点来暂停代码,使其更接近错误的可能位置,而不是单步执行每一行代码。

第五步:设置 line-of-code breakpoint


line-of-code breakpoint是常见的一种断点类型。使用它可以实现暂停任意一行代码,而不是一行一行的去执行。

  • updateLabel()函数的最后一行代码:
  label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
  • 看到代码最左边的 32 这个代码行号了吗?是的,直接点击它,此时会将行号高亮起来,代码在执行到 32 行之前会暂停执行:

Debug JavaScript(调试、debugger)

  • 现在可以看到行号 29、30、31 对应的代码最右侧有该行代码表达式的值,这对调试代码有很大帮助。

第六步:检查变量值


根据上面第五步中代码最右侧的表达式的值可以发现,变量 addend1、addend2、sum的值用引号括起来了,说明它被评估为了 string 类型。现在我们找到了产生bug 的原因,结果应该是 number 类型。以下是开发者工具提供的检查变量的方式:

  • 方式一:使用Scope

    • 点击Scope,可以看到Scope 的下方区域,里面包含了当前执行上下文的变量信息,以及全局的变量信息。双击变量值可以进行修改。

Debug JavaScript(调试、debugger)

  • 方式二:使用Watch

    • 点击Watch ,可以看到Watch 的下方区域,里面可以看到这个符号+ ,点击它添加任意表达式,可以实时监听表达式值的变化,比如可以监听sum值的类型。

Debug JavaScript(调试、debugger)

  • 方式三:使用Console

    • Sourcestab下,按esc可以将Console调出来。Console除了可以查看报错信息外,还可以在当前执行上下文中进行变量的操作。比如此时就可以使用变量addend1、addend2、sum的值,因为代码在 32 行之前暂停,处于updateLabel()的上下文环境中,这时这些变量是存在的。之后输入如下代码:
    • parseInt(addend1) + parseInt(addend2)
      
    • 此时看到控制台打印的结果正是我们需要的正确值 5
    • Debug JavaScript(调试、debugger)

第七步:修复 bug


现在已经知道产生 bug 的原因了,当前任务就是修复它。无需到源代码中操作,在开发者工具就可以实现。在开发者工具中修复好之后,保正没有问题,再回到源代码中写入正确的代码即可。当然应该可以使用工作区直接在开发者工具中编辑,覆盖源代码,无需回到源代码中操作,目前我也没有使用过这种方式,以后可以尝试一下,现在先引用官方的一句话:

This workflow only applies a fix to the code that is running in your browser. It won’t fix the code for all users that visit your page. To do that, you need to fix the code that’s on your servers. You can, however, edit files in DevTools and save them to your sources with Workspaces.

  • 回到代码编辑区,将 31 行的代码var sum = addend1 + addend2;var sum = parseInt(addend1) + parseInt(addend2)代替,然后按 Command + S (Mac) 或 Control + S(Windows、Linux)保存更改。
  • 点击第四步中截图里的序号 6(Activate/Deactivate breakpoints),发现它高亮起来了,说明此时所有的断点都被禁用,代码不会暂停了。
  • 点击Add Number 1 and Number 2 按钮,这时按钮下方的标签显示 2 + 3 = 5。这就是正确的值。

Debug JavaScript(调试、debugger)

个人见解


现在就聊一聊使用console.log调试代码好还是使用断点调试代码好,我先阐明我的观点:本人更倾向于使用断点调试代码,虽然前期对于功能不是很熟悉,但是随着对开发者工具的深入了解,发现它对调试代码的能力是很强大,高效的,同时也有助于我们对代码运行时逻辑的理解。(当然也不要那么死板,两者可以结合使用)使用console.log调试代码,比如下面这样:

function updateLabel() {
  var addend1 = getNumber1();
  console.log('addend1:', addend1);
  var addend2 = getNumber2();
  console.log('addend2:', addend2);
  var sum = addend1 + addend2;
  console.log('sum:', sum);
  label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
}

使用console.log调试代码,需要回到源代码中,编辑好之后保存,然后再到浏览器中查看。这样每次排产问题,都会进行重复的操作:保存、查看。有时候项目很大,跑一次需要花费一定时间,非常影响效率。而在开发者工具中可以更加快速高效的完成相同的事情,优点如下:

  • 使用console.log(),需要手动打开源代码,找到相关代码,插入console.log()语句,然后重新加载页面,才能在Console中看到消息。使用断点,您甚至可以在不知道代码结构的情况下暂停相关代码;
  • 在 console.log() 语句中,您需要明确指定要检查的每个值。通过断点,开发者工具会及时向您显示所有变量在该时刻的值。有时,有些变量会影响您的代码,您甚至都没有意识到。

总结


至此,分享内容到此结束。本篇文章围绕怎样在浏览器中使用断点的方式调试代码,通过一步一步操作,最终解决问题。同时也分享了自己对于使用console.log调试代码和使用断点调试代码的个人见解,如有不妥之处、疑问、不同观点,欢迎评论区讨论!

原文链接:https://juejin.cn/post/7240662396020867130 作者:RED

(0)
上一篇 2023年6月5日 上午10:05
下一篇 2023年6月5日 上午10:16

相关推荐

发表回复

登录后才能评论