10 月 23 - 25 日,QCon 上海站即将召开,现在大会已开始正式报名,可以享受 8 折优惠 了解详情
写点什么

如何用浏览器调试器代替 console.log() ?

  • 2018-11-13
  • 本文字数:2407 字

    阅读完需:约 8 分钟

如何用浏览器调试器代替console.log() ?

对于初级开发人员来说,代码调试是一个不小的挑战。本文通过案例实战介绍使用浏览器自带的调试工具替代 console.log()打印来定位 bug 的方法。


自从成为一名开发人员,我遇到了很多的困难。对于一名初级开发人员来说,最常见的一个挑战就是代码调试。最开始,当我发现可以在 chrome 的控制台中通过 console.log()打印值来定位 bug 的时候,我以为我找到了代码调试的圣杯,结果却证明这种方法非常低效。以下是一些经典的案例供大家调侃:


console.log(‘Total Price:’, total) //确认该值是否已储存


console.log(‘Here’) //确认某个函数是否执行


我想大部分开发人员应该已经意识到这并不是最理想的调试方法,肯定有更好的方法。


非常令人开心的是,浏览器自带的调试工具就是一个更好的方法。以下将以 Chrome 开发者工具为例具体分析。


在这篇文章中,我将会介绍如何打断点,单步执行代码,监听表达式以及在 Chrome 开发者工具中修改代码。


为了更好的理解这篇文章,您需要使用以下案例所需要的代码块,点击这里

第一步:重现 bug

首先需要做的是重现 bug:


1.示例是一个简单的小费计算器。如果您还没有打开


示例代码,请点击这里


2.在 Entree 1 框中输入 12


3.在 Entree 2 框中输入 8


4.在 Entree 3 框中输入 10


5.在 Tax 框中输入 10


6.选择 20%的小费比值


7.点击 Calculate Bill 按钮。计算后的值应为 39.6,但是我们得到的结果却是 14105.09,两个值相差非常的大!


第二步:学会使用 Sources 面板

为了能够在 Chrome 中调试这个案例,您必须习惯使用它的开发者工具栏。Mac 系统同时按住 Command+Option+I 按钮,Linux 系统同时按住 Control+Shift+I 即可打开 Chrome 浏览器的开发者工具。



点击顶部的 Sources 面板之后,下面会出现三个调试面板。从左往右依次是文件导航器,源代码编辑器以及调试窗口。在开始第三步之前,您可以点击熟悉下它们。

第三步:设置第一个断点

在向您展示如何设置第一个断点之前,我先通过 console.log()打印来演示下我要表达的意思。很明显,这个程序在执行的时候进行了计算操作。我们可以通过以下操作来调试程序。



幸运的是,在浏览器的开发者工具中,我们只需要简单的设置一个断点,然后逐步执行代码,就可以直接在浏览器中看到每一步的值,再也不需要执行上面那些繁琐的操作。


浏览器会找到我们所设置的断点,当代码执行到断点处的时候,浏览器会暂停代码的执行,这样您就可以自行调试了。接下来我们来说说如何设置断点。


在上述案例中,我们会在执行最开始的时候,通过设置鼠标事件来设置断点。


在调试窗口中展开“Event Listener Breakpoints”,在下拉框里面展开“Mouse”,然后勾选”click”按钮。


现在,当你点击 Calculate Bill 按钮的时候,调试器将在第一个函数”onClick()”的第一行代码暂停。如果 bug 不在这里,点击工具栏的播放按钮即可跳过这次暂停。


##第四步:逐步执行代码


在所有的调试工具中,开发者都有两种方式来执行代码。我们既可以“进入”,也可以“跳过”后面的一个函数调用。


选择“进入”,浏览器将会逐步执行函数内的每一行代码。



进入下一个函数


选择“跳过”,浏览器将会跳过整个函数,但是这并不影响函数的执行。



跳过下一个函数


以下是单步执行代码的示例。可以看到前三个 Entree 框的值显示在右侧的 Scope 窗口中。


第五步:设置代码行断点

浏览器逐步执行代码的能力非常炫酷,对吧?但是您是否觉得有点麻烦?通常来说,我们只想要知道特定的值。想要解决这个麻烦,我们可以设置代码行断点。


作者备注:正是代码行断点方法让我抛弃了 console.log()方法,并从此爱上了 Chrome 开发者工具。


设置代码行断点,只需要点击您想要查看更多信息的代码行数字编号即可。然后像往常一样运行代码,浏览器会自动在你设置断点的那一行暂停执行,而不需要逐步执行每一个函数。


注意:如果遇到了问题,请先检查是否取消选中了鼠标下的单击复选框。



如您所见,3 个数据小计之后的值显示为”10812”。我输入的值在右边的 Scope 窗口中显示,同时代码行中也有相应的提示。


嗯…我想我应该已经知道问题出现在哪里了,有可能是字符串拼接导致的问题。


接下来,让我们监听表达式来验证我的想法。

第六步:监听表达式

我们现在已经知道三个输入框的值并没有正确相加,那么让我们监听下这三个值。


监听表达式会提供有关代码中任何给定变量或表达式的更多信息。


如何“监听”特定的值?点击顶部 Watch 面板,面板展开后再点击右边的加号,然后就可以输入您想要监听的变量名称或者是表达式名称了。


以上示例中,我们需要监听第一个 Entree 框的值,以及值的类型。



啊!我想我终于找到了问题所在。第一个输入框的值存储的是字符串类型!问题似乎发生在获取输入框值的时候,或许,querySelector()方法才是罪魁祸首,另外的两个值也应该受到这个方法的影响了。接下来我们将进一步调试,然后在开发者工具栏中修改我们的代码。

第七步:修改代码

经过进一步的了解,问题确实出在 querySelector()方法上!



那么我们如何解决这个问题呢?如 74 行代码所示,我们可以简单地使用像 Number(getEntree1())这样的方法将获取到的字符串强制转换为数值。


想要修改代码,您需要打开”sources”左边的”elements”面板。如果没有看到 javascript 代码,打开 script 标签即可。然后在面板上右键选择”edit as html”,就可以开始修改了。



如果您使用的是工作区,就可以轻松地保存并立即查看更新的代码。如果不是,您将需要使用 command + s(mac)或者 control+s(linux)命令保存网页的本地副本。


然后,您可以打开本地副本查看更新了。



搞定!


本文中的调试方法灵感来自于 Kayce Basques 的文章”在 Chrome 开发者工具中开启调试 Javascript”,该方法已被 developers.google.com 所采用。


演示代码: https://github.com/paragzaveri/chromeDevTools


英文原文:https://medium.com/datadriveninvestor/stopping-using-console-log-and-start-using-your-browsers-debugger-62bc893d93ff


2018-11-13 14:282506

评论 4 条评论

发布
用户头像
还是console.log()比较快速
2018-11-20 09:48
回复
用户头像
这个面对现在的 webpack 友好吗
2018-11-14 15:35
回复
别担心,有sourcemap
2018-11-28 21:15
回复
用户头像
真是好文章啊
2018-11-13 18:10
回复
没有更多了
发现更多内容

如何快速构建服务发现的高可用能力

阿里巴巴云原生

阿里云 开源 微服务 云原生

专访 OpenKruise 负责人:现在的云原生应用自动化发展到什么程度了?

阿里巴巴云原生

阿里云 开源 云原生

给面试加点硬菜:延迟任务场景,该如何提高吞吐量和时效性!

小傅哥

小傅哥 架构设计 Redis 6.0 任务系统

Kotlin语法手册(三)

寻找生命中的美好

android kotlin 安卓

还没有表白神器?情人节来喽,快为心爱的她送上一份专属的礼物吧~

是Dream呀

Python 2月月更

独家下载!阿里云云原生携 10+ 技术专家带来《云原生与云未来的新可能》

阿里巴巴云原生

阿里云 Kubernetes 云原生 电子书

人人都是 Serverless 架构师 | 现代化 Web 应用开发实战

阿里巴巴云原生

阿里云 Serverless 云原生

DGIOT 工业物联网开源平台简介

dgiot

物联网 2月月更 2月日更 dgiot dgiot物联网

为什么start方法不能重复调用?而run方法却可以?

王磊

Java 面试

Go 语言Web开发很简单:使用模板将视图与逻辑分离

宇宙之一粟

Go 语言 Web应用开发 2月月更

流量录制与回放在vivo的落地实践

vivo互联网技术

测试工具 回归测试 流量回放

DevOps进阶(三)走近 DevOps 工程师

No Silver Bullet

DevOps 敏捷 jenkins 2月月更

美团动态线程池实践思路,开源了

yanhom

Java 线程池 动态调整线程池参数 动态线程池 美团线程池

云原生落地大爆发,企业和开发者如何把握先机?

阿里巴巴云原生

阿里云 云原生 ACK ACK Anywhere

Linux系统编程-进程间通信(mmap内存映射)

DS小龙哥

2月月更 mmap内存映射

甜言蜜语生成器、定时问候邮件机…开源程序员为这个情人节付出太多

腾源会

开源

教程直播第8期|一文详解 OceanBase 社区版生态工具 ODP & OCP

OceanBase 数据库

数据库 分布式 直播 OceanBase 开源

阿里云容器服务差异化 SLO 混部技术实践

阿里巴巴云原生

阿里云 Kubernetes 云原生 混部技术

SSH远程连接命令执行没反应不报错问题解决(-bash: fork: retry: Resource temporarily unavailable.[资源暂时不可用])

山河已无恙

SSH Linxu 2月月更

企业为什么要做应用多活?

阿里巴巴云原生

阿里云 云原生 容灾

剑指Offer——企业级项目中分层的含义与依据及多态的优势

No Silver Bullet

封装 offer 继承 多态 2月月更

花灯照 人笑颜|OceanBase祝大家工作生活都和元宵一样甜

OceanBase 数据库

数据库 分布式 开发者 OceanBase 开源 元宵

国内唯一!阿里云容器服务进入 Forrester 领导者象限

阿里巴巴云原生

阿里云 云原生 容器平台

平安保险基于 SPI 机制的 RocketMQ 定制化应用

阿里巴巴云原生

阿里云 云原生 消息队列 开源云工具

微信朋友圈高性能架构方案

Geek_36cc7c

虎啸春来!丰树电子与中联重科签署战略合作协议

联营汇聚

大数据培训:在 flink 中使用 hive udf的原因分析

@零度

flink 大数据开发

Spring Boot Serverless 实战系列 | 性能调优

阿里巴巴云原生

阿里云 Serverless 架构 云原生

《MySQL入门很轻松》第4章:数据表中能存放的数据类型

乌龟哥哥

数据库 2月月更

计算机网络面试知识点

yuexin_tech

面试 计算机网络

详细讲解mybatis的执行流程

编程江湖

mybatis

如何用浏览器调试器代替console.log() ?_大前端_Parag Zaveri_InfoQ精选文章