谷歌浏览器代码调试官方教程!个人翻译版

调试JavaScript

本教程教你调试 DevTools 中的任何 JavaScript 问题的基本工作流程。请继续阅读,或者观看本教程的视频版本。

第一步:重现bug

  1. 找到一系列能够持续重现 bug 的操作始终是调试的第一步。
  2. 单击"打开演示"。演示将在一个新选项卡中打开
  1. 笔者注:演示是一个网页,需要科学上网,这里直接提供该网页的代码
js 复制代码
<html>
  <head>
    <link rel="shortcut icon" href="/devtools-samples/favicon-96x96.png">
    <title>Demo: Get Started Debugging JavaScript with Chrome DevTools</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
      h1 {
        font-size: 1.5em
      }
      input, button {
        min-width: 72px;
        min-height: 36px;
        border: 1px solid grey;
      }
      label, input, button {
        display: block;
      }
      input {
        margin-bottom: 1em;
    }
  </style>
  </head>
  <body>
    <h1>Demo: Get Started Debugging JavaScript with Chrome DevTools</h1>
    <label for="num1">Number 1</label>
    <input placeholder="Number 1" id="num1">
    <label for="num2">Number 2</label>
    <input placeholder="Number 2" id="num2">
    <button>Add Number 1 and Number 2</button>
    <p>1 + 2 = 12</p>
  <script src="get-started.js"></script>
  </body>
</html>
js 复制代码
function onClick() {
  if (inputsAreEmpty()) {
    label.textContent = 'Error: one or both inputs are empty.';
    return;
  }
  updateLabel();
}
function inputsAreEmpty() {
  if (getNumber1() === '' || getNumber2() === '') {
    return true;
  } else {
    return false;
  }
}
function updateLabel() {
  var addend1 = getNumber1();
  var addend2 = getNumber2();
  var sum = addend1 + addend2;
  label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
}
function getNumber1() {
  return inputs[0].value;
}
function getNumber2() {
  return inputs[1].value;
}
var inputs = document.querySelectorAll('input');
var label = document.querySelector('p');
var button = document.querySelector('button');
button.addEventListener('click', onClick);

  1. 在数字1文本框中输入5。
  2. 在数字2文本框中输入1。
  3. 单击添加数字1和数字2。按钮下面的标签写着5 + 1 = 51。结果应该是6。这就是你要解决的问题。

图1:5 + 1的结果是51,应该是6。

第二步: 熟悉资源面板的用户界面

DevTools 为不同的任务提供了许多不同的工具,比如更改 CSS、分析页面加载性能和监视网络请求。资源面板是调试 JavaScript 的地方。

  1. 按 Command + Option + i (Mac)或 Control + Shift + i (Windows,Linux)打开 DevTools。这个快捷键打开控制台面板。

图2. 控制台面板

  1. 点击资源标签。

图3.资源面板

源代码面板界面有3个部分:

图4. source 面板 UI 的3个部分

  1. 文件导航窗格:这里列出了页面请求的每个文件
  2. 代码编辑器窗格:在"文件导航器"窗格中选择一个文件后,该文件的内容将显示在这里
  3. 调试窗格:检查页面 JavaScript 的各种工具。如果" DevTools"窗口较宽,则此窗格将显示在"代码编辑器"窗格的右侧

第三步: 使用断点暂停代码

调试此类问题的一种常见方法是在代码中插入大量console.log()语句,以便在脚本执行时检查值。例如:

js 复制代码
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. log()语句,然后重新加载页面,以便在Console中查看消息。使用断点,您甚至可以在不知道代码结构的情况下暂停相关代码。
  • 在你的console.log()语句中,你需要显式地指定你想要检查的每个值。使用断点,DevTools会显示出所有变量在那个时刻的值。有时,有一些变量会影响代码,而您甚至没有意识到这些变量。

简而言之,与console.log()方法相比,断点可以帮助您更快地找到并修复bug。

如果你退后一步,想想这个应用程序是如何工作的,你可以做出一个有根据的猜测,错误的和(5 + 1 = 51)是在与添加1号和2号按钮相关联的单击事件侦听器中计算出来的。因此,您可能希望在单击侦听器执行时暂停代码。事件监听器断点可以让你做到这一点:

  1. 在JavaScript调试窗格中,单击事件侦听器断点以展开该部分。DevTools显示了一系列可扩展的事件类别,比如动画和剪贴板。
  2. 在鼠标事件类别旁边,单击"展开" 。DevTools显示了一个鼠标事件列表,比如单击和鼠标下拉。每个事件旁边都有一个复选框。
  3. 选中"单击"复选框。DevTools现在被设置为在任何单击事件监听器执行时自动暂停。 图5。启用"单击"复选框
  4. 回到演示中,再次单击Add Number 1和Number 2。DevTools暂停演示,并在源代码面板中突出显示一行代码。DevTools应该在这行代码上暂停:function onClick(){如果你在另一行代码上暂停,按恢复脚本执行 直到你在正确的行上停下来。注意:如果您在不同的行上暂停,您有一个浏览器扩展,它在您访问的每个页面上注册一个单击事件监听器。您被暂停在扩展的单击监听器。如果您使用Incognito Mode私有浏览(禁用所有扩展),您可以看到您每次都暂停在正确的代码行上。

事件监听器断点只是DevTools中可用的许多类型的断点之一。记住所有不同的类型是值得的,因为每种类型最终都能帮助您尽可能快地调试不同的场景。请参阅使用断点暂停代码以了解何时以及如何使用每种类型

第四步: 逐步完成代码

错误的一个常见原因是脚本以错误的顺序执行。逐步执行代码使您能够遍历代码的执行,一次一行,并准确地找出代码以不同于预期的顺序执行的位置。试一试:

  1. 在DevTools的Sources面板上,单击进入一个函数调用按钮 一步一步地执行onClick()函数。DevTools突出显示了下面这行代码:
js 复制代码
if (inputsAreEmpty()) {
  1. 单击下一步函数调用。DevTools执行inputsAreEmpty()而不进入它。注意DevTools是如何跳过几行代码的。这是因为inputsAreEmpty()被求值为false,所以if语句的代码块没有执行。

这就是单步执行代码的基本思想。如果您查看get-start .js中的代码,您可以看到错误可能在updateLabel()函数的某个地方。您可以使用另一种类型的断点来暂停靠近错误可能位置的代码,而不是遍历每一行代码。

第五步:设置一个代码行断点

代码行断点是最常见的断点类型。当你有一个特定的代码行,你想暂停,使用行代码断点:

  1. 看看updateLabel()中的最后一行代码:
js 复制代码
label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
  1. 在代码的左边,您可以看到这一行代码的行号,也就是32。点击32。DevTools在32个图标上放了一个蓝色图标。这意味着这一行上有一个代码行断点。DevTools现在总是在这行代码执行之前暂停。
  2. 单击恢复脚本执行 . 脚本继续执行,直到第32行。在第29、30和31行,DevTools将addend1、addend2和sum的值打印到每行分号右侧。 图6。DevTools在32行的代码行断点上暂停

第六步:检查变量值

addend1、addend2和sum的值看起来可疑。它们用引号括起来,这意味着它们是字符串。这是解释bug原因的一个很好的假设。现在是收集更多信息的时候了。DevTools提供了很多工具来检查变量值。

方法一1: 面板范围

当您在一行代码上暂停时,Scope窗格会显示当前定义了哪些局部和全局变量,以及每个变量的值。如果可以的话,它还显示了闭包变量。双击一个变量值来编辑它。当您没有在一行代码上暂停时,Scope窗格是空的。

图7。面板范围

方法二:观察表达式

Watch Expressions选项卡允许您监视随时间变化的变量值。顾名思义,Watch表达式不仅仅局限于变量。您可以在Watch expression中存储任何有效的JavaScript表达式。试一试:

  1. 点击Watch选项卡.
  2. 单击Add表达式 .
  3. 输入 typeof sum.
  4. 按回车。DevTools显示类型sum: "string"。冒号右边的值是手表表达式的结果. 图8。Watch Expression窗格(右下),

在创建typeof sum Watch之后表达式。如果您的DevTools窗口很大,那么监视表达式窗格在右侧,在事件侦听器断点窗格的上方。

正如所怀疑的,当sum应该是一个数字时,它是作为一个字符串计算的。您现在已经确认了这就是bug的原因。

方法3:控制台

除了查看Console .log()消息外,您还可以使用Console来评估任意的JavaScript语句。在调试方面,您可以使用Console测试bug的潜在修复。试一试:

  1. 如果没有打开控制台抽屉,请按Escape键打开它。它会在DevTools窗口的底部打开。
  2. 在控制台中输入parseInt(addend1) + parseInt(addend2)。这条语句之所以有效,是因为您在addend1和addend2在作用域中的一行代码上暂停了。
  3. 按回车。DevTools计算该语句并输出6,这是您希望演示程序生成的结果。 图9。在计算parseInt(addend1) + parseInt(addend2)之后,控制台抽屉。

第七步:修复

你已经找到了bug的修复方法。剩下的工作就是通过编辑代码并重新运行演示来尝试修复。你不需要离开DevTools去应用修复。你可以直接在DevTools UI中编辑JavaScript代码。试一试:

  1. 单击恢复脚本执行 .
  2. 在代码编辑器中,替换第31行,
js 复制代码
var sum = addend1 + addend2  

改为

js 复制代码
var sum = parseInt(addend1) + parseInt(addend2).
  1. 按Command+S (Mac)或Control+S (Windows, Linux)保存更改。.
  2. 单击禁用断点 . 它变成蓝色表示它是活跃的。当设置了这个时,DevTools会忽略您设置的任何断点
  3. 用不同的值试一下这个演示。演示程序现在可以正确计算了。

注意: 此工作流仅对浏览器中运行的代码应用修复。它不会为所有访问您页面的用户修复代码。为此,您需要修复服务器上的代码。

下一步

恭喜你!现在您知道了如何在调试JavaScript时充分利用Chrome DevTools。在本教程中学习的工具和方法可以为您节省无数的时间。

本教程只介绍了设置断点的两种方法。DevTools提供了许多其他方式,包括:

  • 仅在您提供的条件为真时触发的条件断点。
  • 捕获或未捕获异常上的断点。
  • 当请求的URL匹配您提供的子字符串时触发的XHR断点。

参阅使用断点暂停代码以了解何时以及如何使用每种类型。

有几个代码步进控件没有在本教程中解释。有关详细信息,请参见逐行代码

使用断点暂停代码

使用断点暂停JavaScript代码。本指南解释了DevTools中可用的每种类型的断点,以及何时使用以及如何设置每种类型的断点。有关调试过程的实践教程,请参见开始在Chrome DevTools中调试JavaScript

何时使用每种断点类型的概述

最著名的断点类型是代码行。但是,设置代码行断点的效率可能很低,特别是当您不知道具体在哪里查找,或者您正在处理一个大型代码库时。通过了解如何以及何时使用其他类型的断点,您可以在调试时节省时间。

断点类型 当你想暂停的时候使用这个
代码行 在代码的精确区域上
条件代码行 在代码的一个确切区域上,但只有在其他条件为真时
DOM 更改或移除特定 DOM 节点或其子节点的代码上
XHR 当 XHR URL 包含字符串模式时
Event listener事件侦听器 在事件之后运行的代码上,如click, is fired. ,被解雇
Exception例外 在抛出已捕获或未捕获异常的代码行上
Function功能 Whenever a specific function is called.

行代码断点

当您知道需要研究的确切代码区域时,请使用代码行断点。DevTools总是在这行代码执行之前暂停。

在DevTools中设置代码行断点:

  1. 单击Sources选项卡
  2. 打开包含要中断的代码行的文件。
  3. 到代码行。
  4. 代码行左边是行号列。点击它。行号列顶部出现一个蓝色图标。

****图1:在第29行设置的代码行断点

代码中的代码行断点

从代码中调用调试器以在该行上暂停。这等同于代码行断点,只是断点是在代码中设置的,而不是在 DevTools UI 中设置的。

js 复制代码
console.log('a');
console.log('b');
debugger;
console.log('c');

条件代码行断点

当您知道需要调查的代码的确切区域,但只希望在其他条件为真时暂停时,使用条件代码行断点。

若要设置条件代码行断点:

  1. 点击资源标签
  2. 打开包含要中断的代码行的文件
  3. 按代码行走
  4. 代码行左边是行号列。右键单击它
  5. 选择 Add conditional breakpoint。在代码行下面显示一个对话框
  6. 在对话框中输入您的条件
  7. 按回车键激活断点。一个橙色的图标出现在行号列的顶部

图2: 在第32行设置的条件代码行断点

管理代码行断点

使用"断点"窗格从单个位置禁用或删除代码行断点。

图3: Breakpoints 窗格显示了两个代码行断点: 一个在 get-started. js 的第15行,另一个在第32行

  • 选中条目旁边的复选框以禁用该断点
  • 右键单击一个条目以删除该断点
  • 右键单击"断点"窗格中的任何位置以停用所有断点、禁用所有断点或删除所有断点。禁用所有断点相当于不检查每个断点。禁用所有断点会指示 DevTools 忽略所有代码行断点,并保留它们的启用状态,以便在重新激活它们时,它们处于与之前相同的状态

图4: Breakpoints 面板中的非激活断点被禁用和透明

DOM 更改断点

如果要在更改 DOM 节点或其子节点的代码上暂停,请使用 DOM 更改断点。

要设置 DOM 更改断点:

  1. 单击 Elements 选项卡
  2. 转到要设置断点的元素
  3. 右键单击元素
  4. 将鼠标悬停在"中断"上,然后选择子树修改、属性修改或节点删除

图5: 创建 DOM 变更断点的上下文菜单

XHR/Fetch 断点

当 XHR 的请求 URL 包含指定的字符串时,要中断时使用 XHR 断点。DevTools 暂停在 XHR 调用 send ()的代码行上。

注意:此特性也适用于Fetch请求。

当你看到你的页面正在请求一个不正确的 URL,并且你想要快速找到导致不正确请求的 AJAX 或者 Fetch 源代码时,这是一个很有帮助的例子。

设置 XHR 断点:

  1. 点击资源标签
  2. 展开 XHR"断点"窗格
  3. 单击添加断点
  4. 输入要断开的字符串。当该字符串出现在 XHR 的请求 URL 中的任何位置时,DevTools 会暂停
  5. 按回车确认

图6: 为 URL 中包含 org 的任何请求在 XHR 断点中创建 XHR 断点

事件侦听器断点

当您希望暂停在事件触发后运行的事件侦听器代码时,请使用事件侦听器断点。您可以选择特定事件(如单击)或事件类别(如所有鼠标事件)。

  1. 点击资源标签
  2. 展开"事件侦听器断点"窗格。 DevTools 显示事件类别的列表,如"动画"
  3. 检查其中一个类别,以便在触发该类别的任何事件时暂停,或者扩展该类别并检查特定事件

图7: 为 deviceorientation 创建一个事件侦听器断点

异常断点

当您希望在抛出已捕获或未捕获异常的代码行上暂停时,请使用异常断点。

  1. 点击资源标签。
  2. 单击"暂停异常"。启用时将变为蓝色。 * * 图8 * * : 暂停异常 * * 按钮
  3. (可选)检查暂停在捕获异常复选框,如果你也想暂停了例外,除了未捕获的。(可选)选中停顿在了例外

图9: 在未捕获的异常上暂停

函数断点

调用 debug (functionName) ,其中 functionName 是希望调试的函数,当您希望在调用特定函数时暂停时调用。可以将 debug ()插入到代码中(如 Console.log ()语句) ,或者从 DevTools 控制台调用它。Debug ()等价于在函数的第一行上设置代码行断点。

js 复制代码
function sum(a, b) {
  let result = a + b; // DevTools pauses on this line.
  return result;
}
debug(sum); // Pass the function object, not a string.
sum();

确保目标函数在范围内

如果要调试的函数不在范围内,DevTools 将引发 ReferenceError。

js 复制代码
(function () {
  function hey() {
    console.log('hey');
  }
  function yo() {
    console.log('yo');
  }
  debug(yo); // This works.
  yo();
})();
debug(hey); // This doesn't work. hey() is out of scope.

如果要从 DevTools 控制台调用 debug () ,那么确保目标函数在作用域中是很棘手的。这里有一个策略:

  1. 在函数作用域中的某个地方设置代码行断点。
  2. 触发断点。
  3. 在DevTools控制台中调用debug(),而代码仍然暂停在你的代码行断点上。
相关推荐
gqkmiss36 分钟前
Chrome 浏览器插件获取网页 iframe 中的 window 对象
前端·chrome·iframe·postmessage·chrome 插件
m0_748247553 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
m0_748255023 小时前
前端常用算法集合
前端·算法
真的很上进3 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203984 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
NiNg_1_2344 小时前
Echarts连接数据库,实时绘制图表详解
前端·数据库·echarts
如若1235 小时前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~5 小时前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语5 小时前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport5 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap