工欲善其事,必先利其器。最近在写代码的时候愈加以为不是代码有多难,而是当代码出了问题该如何调试,如何追溯本源,这才是最难的。javascript
响应这个要求,我决定写一个关于调试实战系列。原本不打算写这个基础篇章,为了整个的完整性。(不喜勿喷)html
注意,如下yifenghua.win域名下线,替换为https://hua1995116.github.io/myblog/vue
打算出三个篇章java
1.急速 debug 实战一 (浏览器 - 基础篇)webpack
3.急速 debug 实战三 (Node - webpack插件,babel插件,vue源码篇)github
因此示例在如下环境经过。web
操做系统: MacOS 10.13.4chrome
Chrome: 版本 72.0.3626.81(正式版本) (64 位)浏览器
可能不少人如今还比较频繁的用着 console.log
的方式调试着代码,这种方式不说他绝对的很差,只是相比之下断点有如下两个优点:
使用 console.log()
,您须要手动打开源代码,查找相关代码,插入 console.log()
语句,而后从新加载此页面,才能在控制台中看到这些消息。 使用断点,无需了解代码结构便可暂停相关代码。
在 console.log()
语句中,您须要明确指定要检查的每一个值。 使用断点,DevTools 会在暂停时及时显示全部变量值。 有时在您不知道的状况下,有些变量会影响您的代码。
1.打开: hua1995116.github.io/myblog/exam…
2.在 Number 1
文本框中输入 5。
3.在 Number 2
文本框中输入 1。
4.点击 Add Number 1 and Number 2
。 按钮下方的标签显示5 + 1 = 51
。 结果应为 6。 这就是咱们须要修正的问题。
第 1 步:重现错误
1.经过按Command+Option+I (Mac)
或 Control+Shift+I(Windows、Linux)
,打开 DevTools。 此快捷方式可打开 Console
面板。
2.点击 Sources 标签。
第 3 步:使用断点暂停代码
若是退一步思考应用的运做方式,您能够根据经验推测出,使用与 Add Number 1 and Number 2 按钮关联的 click 事件侦听器时计算的和不正确 (5 + 1 = 51)
。 所以,您可能须要在 click
侦听器运行时暂停代码。 Event Listener Breakpoints 可以让您完成此任务:
function onClick() {
复制代码
若是是在其余代码行暂停,请按 Resume Script Execution 继续执行脚本, 直到在正确的代码行暂停为止。
一个常见的错误缘由是脚本执行顺序有误。 能够经过单步调试代码一次一行地检查代码执行状况,准确找到执行顺序异常之处。 当即尝试:
在 DevTools 的 Sources 面板上,点击 Step into next function call 单步执行时进入下一个函数调用,以便一次一行地单步调试 onClick() 函数的执行。 DevTools 突出显示下面这行代码:
if (inputsAreEmpty()) {
复制代码
点击 Step over next function call 单步执行时越过下一个函数调用。 DevTools 执行但不进入 inputsAreEmpty()
。 请注意 DevTools 是如何跳过几行代码的。 这是由于 inputsAreEmpty()
求值结果为 false,因此 if
语句的代码块未执行。
这就是单步调试代码的基本思路。 若是看一下 get-started.js
中的代码,您会发现错误多半出在 updateLabel()
函数的某处。 您可使用另外一种断点来暂停较接近很可能出错位置的代码,而不是单步调试每一行代码。
代码行断点是最多见的断点类型。 若是您想在执行到某一行代码时暂停,请使用代码行断点:
看一下 updateLabel()
中的最后一行代码:
label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
复制代码
在这行代码的左侧,您能够看到这行代码的行号是 32。 点击 32。 DevTools 会在 32 上方放置一个蓝色图标。 这意味着这行代码上有一个代码行断点。 DevTools 如今始终会在执行此行代码以前暂停。
点击 Resume script execution 继续执行脚本 。 脚本将继续执行,直到第 32 行。 在第 29 行、第 30 行和第 31 行上,DevTools 会在各行分号右侧输出 addend1
、addend2
和 sum
的值。
addend1
、addend2
和 sum
的值疑似有问题。 这些值位于引号中,这意味着它们是字符串。 这个假设有助于说明错误的缘由。 如今能够收集更多信息。 DevTools 可提供许多用于检查变量值的工具。
方法 1:Scope 窗格 在某代码行暂停时,Scope 窗格会显示当前定义的局部和全局变量,以及各变量值。 其中还会显示闭包变量(若是适用)。 双击变量值可进行编辑。 若是不在任何代码行暂停,则 Scope 窗格为空。
方法 2:监视表达式 Watch Expressions 标签可以让您监视变量值随时间变化的状况。 顾名思义,监视表达式不只限于监视变量。 您能够将任何有效的 JavaScript 表达式存储在监视表达式中。 当即尝试:
点击 Watch 标签。 点击 Add Expression 添加表达式。 输入 typeof sum
。 按 Enter
键。 DevTools 会显示 typeof sum: "string"
。 冒号右侧的值就是监视表达式的结果。
正如猜测,sum 的求值结果本应是数字,而实际结果倒是字符串。 如今已肯定这就是错误的缘由。
方法 3:控制台 除了查看 console.log()
消息之外,您还可使用控制台对任意 JavaScript 语句求值。 对于调试,您可使用控制台测试错误的潜在解决方法。 当即尝试:
若是您还没有打开 Console 抽屉式导航栏,请按 Escape 将其打开。 该导航栏将在 DevTools 窗口底部打开。 在 Console 中,输入 parseInt(addend1) + parseInt(addend2)
。 此语句有效,由于您会在特定代码行暂停,其中 addend1
和 addend2
在范围内。 按 Enter
键。 DevTools 对语句求值并打印输出 6
,即您预计演示页面会产生的结果。
您已找到修正错误的方法。 接下来就是尝试经过编辑代码并从新运行演示来使用修正方法。 您没必要离开 DevTools 就能应用修正。 您能够直接在 DevTools UI 内编辑 JavaScript 代码。 当即尝试:
var sum = addend1 + addend2
替换为 var sum = parseInt(addend1) + parseInt(addend2)
。 3.按 Command+S (Mac)
或 Control+S(Windows、Linux)
以保存更改。断点类型 | 状况 |
---|---|
代码行 | 在确切的代码区域中。 |
条件代码行 | 在确切的代码区域中,且仅当其余一些条件成立时。 |
DOM | 在更改或移除特定 DOM 节点或其子级的代码中。 |
XHR | 当 XHR 网址包含字符串模式时。 |
事件侦听器 | 在触发 click 等事件后运行的代码中。 |
异常 | 在引起已捕获或未捕获异常的代码行中。 |
函数 | 任什么时候候调用特定函数时。 |
在知道须要调查的确切代码区域时,可使用代码行断点。 DevTools 始终会在执行此代码行以前暂停。
在 DevTools 中设置代码行断点:
在代码中调用 debugger
可在该行暂停。 此操做至关于使用代码行断点,只是此断点是在代码中设置,而不是在 DevTools 界面中设置。
console.log('a');
console.log('b');
debugger;
console.log('c');
复制代码
若是知道须要调查的确切代码区域,但只想在其余一些条件成立时进行暂停,则可以使用条件代码行断点。
若要设置条件代码行断点:
使用 Breakpoints 窗格能够从单个位置停用或移除代码行断点。
显示两个代码行断点的 Breakpoints 窗格:一个代码行断点位于 get-started.js
第 15 行,另外一个位于 第 32 行
若是想要暂停更改 DOM 节点或其子级的代码,可使用 DOM 更改断点。
若要设置 DOM 更改断点:
Subtree modifications: 在移除或添加当前所选节点的子级,或更改子级内容时触发这类断点。 在子级节点属性发生变化或对当前所选节点进行任何更改时不会触发这类断点。
Attributes modifications:在当前所选节点上添加或移除属性,或属性值发生变化时触发这类断点。
Node Removal:在移除当前选定的节点时会触发。
若是想在 XHR 的请求网址包含指定字符串时中断,可使用 XHR 断点。 DevTools 会在 XHR 调用 send()
的代码行暂停。
注:此功能还可用于 Fetch 请求。
例如,在您发现您的页面请求的是错误网址,而且您想要快速找到致使错误请求的 AJAX 或 Fetch 源代码时,这类断点颇有用。
若要设置 XHR 断点:
若是想要暂停触发事件后运行的事件侦听器代码,可使用事件侦听器断点。 您能够选择 click
等特定事件或全部鼠标事件等事件类别。
若是想要在引起已捕获或未捕获异常的代码行暂停,可使用异常断点。
若是想要在调用特定函数时暂停,能够调用 debug(functionName)
,其中 functionName
是要调试的函数。 您能够将 debug()
插入您的代码(如 console.log()
语句),也能够从 DevTools 控制台中进行调用。 debug()
至关于在第一行函数中设置代码行断点。
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
。
(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()
,则很难确保目标函数在范围内。 下面介绍一个策略:
debug()
。咱们在调试一些 hover 属性的时候,每每想要调整 hover 后显示的元素,可是每当咱们移到观察此元素的时候就会消失。这使得调试很是不方便。下面就提供几种场景,分别来给出调试的方案。
demo: hua1995116.github.io/myblog/exam…
单纯的 hover 属性咱们只须要找到触发的元素。在这里是咱们 button。因此咱们在 elements 中找到咱们对应的 hover 元素。右键-> force state -> :hover
若是是经过 mouse (鼠标事件来触发的)而且触发元素是写在触发元素内的状况。能够经过在当前触发元素。右键 -> Break on -> subtree modifications。 而后再次触发,选择跳过断点。就可使得元素出现。
若是是经过 mouse (鼠标事件来触发的)而且触发元素是写在触发元素外的状况。能够经过断点触发来阻断。(此方法也兼容 mouser inner 的状况)。当触发元素的时候按下 F8 (Windwos)
/ command + \ (Mac)
developers.google.com/web/tools/c…
友情连接: huayifeng.top/