做前端页面,用JavaScript 在调试 Bug 时有哪些技巧?

原链接:https://www.zhihu.com/question/35667558/answer/530643532

编程新手刚开始查找和修复 bug 还是比较困难的,你可能会随机使用 console.log(),试图让代码正确运行。看了本文再也不用这么干了!

下面就教你一个调 bug 的正确姿势。你会学习如何使用 Chrome 开发者工具设置断点,逐步调试代码。这种工作方法能让你查找和修复 bug 的效率大幅提高。

虽然这篇教程展示的是怎么调试一个具体的 bug,但是整体工作思路对调试任何类型的 JavaScript bug 都是有指导意义的。

步骤1:重现 bug

调试 bug 的第一步就是重现 bug。所谓“重现 bug”就意味着要找到一系列持续导致出现这个 bug 的操作。你可能需要多次重现 bug,所以尽可能地减少不必要的步骤。

按照如下指令来重现本教程需要修复的 bug。

这是我们本教程会使用的网页,确保以新的标签:Demo: Get Started Debugging JavaScript with Chrome DevTools

在 demo 中,在“Number 1”文本框中输入 5

在“Number 2”文本框中输入数字 2

点击“Add Number 1 and Number 2”按钮

查看输入和按钮下方的标签,显示 5 + 1 = 51.

这不,bug 来了,这里结果明显错了,应该是 6。这就是你要修复的 bug。

步骤2:使用断点暂停代码

Chrome 开发者工具(以下简称 DevTools)能让你在代码运行期间暂停代码,并检查此刻所有变量的值。暂停代码的工具叫做 Breakpoint。试试吧:

回到 demo,按 Command+Option(Mac)或 Ctrl+shift+I(Windows,Linux)打开DevTools

点击“Source”标签

点击“Event Listener Breakpoints”(事件监听断点)展开该部分。DevTools 会展示一列可扩展的事件类别,比如 Animation和Clipboard

在“Mouse”事件类别旁边点击“Expand”

检查“click”复选框

<img src="https://pic2.zhimg.com/v2-59cc59b530364c601a704dc3b5a5a509_b.jpg" data-caption="" data-size="normal" data-rawwidth="800" data-rawheight="536" class="origin_image zh-lightbox-thumb" width="800" data-original="https://pic2.zhimg.com/v2-59cc59b530364c601a704dc3b5a5a509_r.jpg">

回到 demo,再次点击“Add Number 1 and Number 2”.DevTools 会暂停 demo,在“Source”面板上高亮显示一行代码,高亮显示的是:

function onClick() {

为啥?

当你选择“Click”时,会在所有的 click 事件上设置一个基于事件的断点。每当节点被点击,并且节点有 click 处理程序时,DevTools 就会在该节点的 click 处理程序的第一行代码处自动暂停。

这里还是要推荐下小编的web前端学习群:867726593,不管你是小白还是大牛,小编我都欢迎,不定期分享干货,包括小编自己整理的一份最新的web前端资料和0基础入门教程,欢迎初学和进阶中的小伙伴。在不忙的时间我会给大家解惑。

步骤3:逐步调试代码

导致出现 bug 的一个常见原因就是脚本运行顺序不正确。逐步调试代码能让你过一遍你的代码运行状况,每次一行,准确找出哪里没有按照预期的顺序执行。试试:

在 DevTools 的“Source”面板上,点击“Step into next function call”

<img src="https://pic3.zhimg.com/v2-3e17e85ee8b8e70d904c1c4d776b292a_b.jpg" data-caption="" data-size="normal" data-rawwidth="18" data-rawheight="26" class="content_image" width="18">

这个按钮能让你逐步查看 onClick() 函数的运行,每次一行。当 DevTools 高亮显示如下一行代码时就停止:

if (inputsAreEmpty()) {

现在点击“Step over next function call”按钮

<img src="https://pic3.zhimg.com/v2-f8aa0d046dfbf1b1a28fdd031ee35e9e_b.jpg" data-caption="" data-size="normal" data-rawwidth="36" data-rawheight="20" class="content_image" width="36">

这会让 DevTools 执行 inputsAreEmpty() 而不进入它。注意 DevTools 跳过了几行代码,这是因为 inputsAreEmpty() 求值结果为 false,所以 if 语句的代码块没有运行。

这就是逐步调试代码的基本理念。如果你查看 get-started.js 中的代码,会发现 bug 可能在 updateLabel() 函数的某个位置。你不必逐行看完所有代码,可以换用另一种断点,在靠近该 bug 的位置暂停代码运行。

步骤4:设置另一个断点

代码行断点是最常见的断点类型。如果想在执行到某一行代码时暂停,就使用代码行断点。试试吧:

查看 updateLabel() 中的最后一行代码,如下所示:

label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;

在代码的左侧,你可以看到这行代码的具体行数:32。点击 32,DevTools 会在 32 上放置一个蓝色图标,表示在这里设置了一个代码行断点。这样以来,DevTools 总会在执行这行代码前暂停。

点击“Resume script execution”按钮

<img src="https://pic3.zhimg.com/v2-d70fc1ddc7b3737276ba2ef3deecaeb6_b.jpg" data-caption="" data-size="normal" data-rawwidth="26" data-rawheight="20" class="content_image" width="26">

这段脚本会持续执行,直到到达你设置了断点的那行代码。

查看 updateLabel() 中已执行的代码行。DevTools 打印输出 addend1,addend2 和 sum 的值。

Sum 的值看着很有问题,求值结果应该是数字才对,但这里却是字符串。这可能就是造成 bug 的原因。

步骤5:检查变量值

造成 bug 的另一个常见原因就是变量或函数产生了异常值。很多开发者会使用 console.log() 来查看值随着时间变化的情况,但使用 console.log() 枯燥又麻烦,而且没有效率。究其原因有二,首先你可能需要手动编辑代码,而且需要大量调用 console.log();其次,你可能无法确定哪个变量和 bug 有关,所以你需要记录很多变量。

DevTools 上有个替代 console.log() 的工具叫 Watch Expressions,使用 Watch Expressions 能够监控变量值随着时间的变化。正如其名,Watch Expressions 并不仅仅能监控变量,你可以将任何有效的 JavaScript 表达式存储在 Watch Expressions 中。试试吧:

在 DevTools 上的“Source”面板上点击“Watch”,然后这部分会展开。

点击“Add Expression”

<img src="https://pic4.zhimg.com/v2-7067d5a4a4c50075cbc26c6b1f1adcc3_b.jpg" data-caption="" data-size="normal" data-rawwidth="20" data-rawheight="20" class="content_image" width="20">

输入 typeof sum

按 Enter 键,DevTools 会显示 typeof sum: "string"。冒号右边的值就是你的 Watch Expression 的结果。

<img src="https://pic1.zhimg.com/v2-30af9a5e742674d281f2d365ff4f26c4_b.jpg" data-caption="" data-size="normal" data-rawwidth="800" data-rawheight="541" class="origin_image zh-lightbox-thumb" width="800" data-original="https://pic1.zhimg.com/v2-30af9a5e742674d281f2d365ff4f26c4_r.jpg">

和我们猜的一样,sum 被处理成了字符串,而本应是个数字。这就是 demo 上的 bug 的来源。

DevTools 中另一个能取代 console.log() 的工具是 Console,可以使用 Console 对任意 JavaScript 语句求值。很多开发者通常在调 bug 时使用 Console 覆盖变量值。在本教程这个例子中,Console 能帮你测试刚发现的 bug 的潜在修复方法。试试:

如果还没打开 Console,按 Escape 键打开它,会在你的 DevTools 窗口底部打开。

在 Console 中输入 parseInt(addend1) + parseInt(addend2)

按 Enter 键,DevTools 会对语句求值,输出 6,也就是开头 Demo 中我们预期程序应该输出的结果。

<img src="https://pic1.zhimg.com/v2-05a303bb328e61b589887ad267c0d2ac_b.jpg" data-caption="" data-size="normal" data-rawwidth="800" data-rawheight="608" class="origin_image zh-lightbox-thumb" width="800" data-original="https://pic1.zhimg.com/v2-05a303bb328e61b589887ad267c0d2ac_r.jpg">

步骤6:应用修复方法

确定一种修复 bug 的潜在方法后,剩下的工作就是编辑代码,尝试修复,并重新运行 demo。不必离开 DevTools 界面就能应用修复。你可以直接在 DevTools UI 里直接编辑 JavaScript 代码。试试吧:

在 DevTools 的“Source”面板的代码编辑器中,用 var sum = parseInt(addend1) + parseInt(addend2) 替换 var sum = addend1 + addend2。就是当前暂停位置上面的那行代码。

按 Command+S(Mac)或 Ctrl+S(Windows,Linux)保存修改。代码背景色变为红色,表示脚本已经在 DevTools 中被修改。

点击“Deactivate breakpoints”

<img src="https://pic3.zhimg.com/v2-2bea76830b3176ebc1e7c0dd41f1210a_b.jpg" data-caption="" data-size="normal" data-rawwidth="19" data-rawheight="17" class="content_image" width="19">

它变为蓝色表示正处于活动状态。如果这样设置,DevTools 会忽略你设置的任何断点。

点击“ Resume script execution”

<img src="https://pic1.zhimg.com/v2-c08b0ef2429def9115ff6272c35642fc_b.jpg" data-caption="" data-size="normal" data-rawwidth="26" data-rawheight="20" class="content_image" width="26">

可以用不同的值试试吧,现在 demo 应该能正确地计算出 sum 值了。

注意:该工作流程只对运行在浏览器中的代码应用修正。它不会为所有运行你的页面的用户修正代码。要想实现该目的,需要修正运行在提供页面的服务器上的代码。

以上就是在 DevTools 中调试 JavaScript bug 的基础知识,本文只介绍了两种设置断点的方法,此外还有不少很多其它方法,比如:

仅在满足你指定的条件时触发的条件断点。

发生已捕获或未捕获异常时触发的断点。

当请求的网址和你提供的子字符串匹配时触发的 XHR 断点。

更多使用 DevTools 调试 bug 的知识,可以查看官方文档

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 生活不易,但还要前行,还要过。老话说,开心也是一天,不开心也是一天,那为什么不选择前者呢? 晚上公司开会,好像一直...
    爱学爱践行的十四阅读 761评论 0 0
  • 待你慢慢回想过程找到答案 才发现为时已晚 时间不等人来不及伸手你就已经走远 等到花开遍野是才想到出发 到达时只有一地荒凉
    EstherVan阅读 312评论 0 1
  • 紧张而有忙碌的,这周工作总算结束了,星期五下午下班。闲下来时想到这个周末要去看看父母。父母在郑州。说走就走,我简单...
    曲曲_0591阅读 136评论 0 0