
作为一名程序员,就算你拥有大圣的 72 变,依然逃脱不了观音的紧箍咒;程序出 Bug 已是家常便饭,但解决问题的能力更加凸现你在公司的地位。本文结合自身实战经验,梳理日常开发中神一般的调试技巧。希望对各位大佬有所参考和借鉴,如有错误的地方,还请指正。
作者居間
大家好,我是河畔一角,一名老前端,平常工作比較忙,文章不經常發布,也希望每次的梳理都能給各路朋友帶來幫助。
前端小白
我曾出过不少课程,学生群也有十几个了,我遇到太多的学生了,一遇到问题,就在群里直接@我:我页面出不来了,快帮我看看 我代码跟你一样,就是不行 控制台报错,怎么办? 怎么打断点 代码怎么调试?
說實話,很無奈,我也特別能理解他們,剛畢業,就像一張白紙一樣,沒有工作經驗,他們對這個行業的認知還處於低位,所以每當遇到問題的時候,一方面是幫助他們排查問題,另一方面也希望幫他們逐步培養他們自主解決問題的能力和方法。
前端菜鳥
console 大法
这个大家肯定不陌生了,遇到问题,可以通过 console 来输出日志,分析问题。
- console.log()
普通日誌輸出,也是前端使用頻次最高的列印方法
function Person() {
this.name = "jack";
this.age = 30;
}
let person = new Person();
// 查看person对象都有哪些属性和方法
console.log(person);
// 可以同时姓名和年龄
console.log(person.name, person.age);
// 也可以使用占位符进行输出
console.log("姓名:%s,年龄:%d", person.name, person.age);
輸出如下:

模板字符串肯定比占位符要更簡單,此處不展開討論。
- console.warn()
用于控制台输出警告信息。同console.log用法一样,只是样式显示不同,通过 warn 方法输出,前面会显示黄色警告标志。
輸出如下:

- console.info()
用于控制台输出说明信息。同 console.log 用法一样,样式也相同。
輸出如下:

- console.error()
用于控制台输出错误信息。同console.log用法一样,只是样式显示不同,通过 error 方法输出,前面会显示错误图标。
輸出如下:

- console.time()
如果想要获取一段代码执行时间,可使用 console.time() 进行计时,使用 console.timeEnd() 结束计时。
// 计时开始
console.time();
for (let i = 0; i < 1000; i++) {
// to-do
}
// 计时结束
console.timeEnd();
輸出如下:

注意:
console.timeEnd()不可以单独使用,必须先定义console.time()否则,会提示:VM578:1 Timer 'default' does not exist
- console.count()
如果想要获取代码执行次数,可使用 console.count()。
for (let i = 0; i < 5; i++) {
// 次数统计
console.count();
}
輸出如下:

也可以傳入一個參數,進行標記,比如: console.count('次數:')
以上是关于通过 console 打印来做调试的比较常用的几个方法,当然还有不少,比较冷门和低频的就不一一列举了。
debugger
除了 console 日志打印外,比较常用的就是 debugger 了,当程序出错或者找不到问题时,我们需要在代码中直接定义 debugger 来暂停程序执行,进而分析问题。
js 複製代碼 let list = [{name:'jack' , age: 30 , info:{score: 70}},{name:'tom' , age: 28}]
for (let item of list) {
debugger;
if (item.info.score > 60) {
console.log(`恭喜你:${item.name}`);
}
}
上述代码很明显会报错,如果程序再复杂一些,就需要我们断点调试了。通过 debugger,我们可以调试得知 item.info 为 null 导致程序报错。
調試如下:

chrome 斷點
无论是在代码中写 console.log 还是 debugger 都是一种侵入式断点,解决问题以后,还需要手工清除,殊不知,浏览器本身也可以打断点?
以 Vue3 为例,我们打开控制台,找到源代码,通过 ctrl + p 搜索用户管理菜单文件 User.vue ,在想要断点的地方,直接点击即可生成断点。

如果不小心打了一堆斷點,如何快速清除?

進入斷點以後,滑鼠懸浮在變量上,會顯示該變量值,懸浮在對象上會顯示對象下的屬性和方法,右側面板包含:監視區、斷點、作用域、調用堆棧等板塊。

chrome 添加帶條件斷點
如果我們調試的代碼是一個循環,可能我們要一條一條執行,直到條件成立時,才能查看對應的變量值,殊不知太浪費時間,也是一種太笨的方法?
- 找到要調試的代碼片段

- 右鍵選擇條件斷點

- 當 userid == 1000002 時,才觸發斷點

- 當條件成立時才會觸發斷點

條件斷點,簡直太好用了,爆贊

前端王者
請求重發
跟後端接口調試時,頁面請求太快,後端來不及看日誌,於是後端會讓前端:再發一次請求,我調試一下 ,於是我們傻乎乎的,就刷新了一下頁面,殊不知瀏覽器自帶請求重發?
操作步驟:
- 打開控制台
- 選擇 network(中文叫網絡)
- 找到要重發的接口
- 右鍵選擇 replay xhr(中文叫重放 xhr)
於是你就看到了驚人的一幕,請求再次發送了...
請求重放前:

請求重放後:

控制台發送請求
如果請求重發的時候,需要修改參數,如何處理?
- 打開控制台
- 選擇 network(中文叫網絡)
- 找到要修改參數的接口
- 右鍵選擇 copy -> copy as fetch (中文叫以 fetch 格式複製)
- 在控制台界面,粘貼
- 修改請求參數,直接回車即可
- 複製請求

- 修改分頁參數為第二頁:

- 回車發送請求

html 節點複製
当页面布局出问题时,我们往往需要通过审查元素进行分析,同时也会在控制台通过 DOM API 来进行读写调试,但是 DOM API 操作起来过于麻烦,殊不知浏览器已自带 api 功能?
- 当选中要查看的
html节点时,会自动生成$0变量

- 控制台直接写
$0便会打印选中的节点

- 用
$或$$代替docuement.querySelector()

这简直太好用了,如果你还不知道,真的就
out了,chrome太懂前端了
javascript 對象複製
有时候我们通过 console.log 打印了一个比较复杂的对象,但是需要一层一层展开进行查看,非常不方便,有什么好办法?
function Person() {
this.name = "jack";
this.age = 30;
}
let person = new Person();
// 查看person对象都有哪些属性和方法
console.log(person);
浏览器自带 copy 函数
1. 输入 copy(person)`

- 直接粘貼
控制台會直接格式化列印改對象,不再需要一層一層展開,是不是賊方便。
更多好用變量如下:
$// 简单理解就是 document.querySelector 而已。$$// 简单理解就是 document.querySelectorAll 而已。$_// 是上一个表达式的值$0-$4// 是最近 5 个 Elements 面板选中的 DOM 元素,待会会讲。dir// 其实就是 console.dirkeys// 取对象的键名, 返回键名组成的数组values// 取对象的值, 返回值组成的数组
本地文件替換遠程
我曾经遇到过一种场景,有一个项目已经部署到服务器上了,但是本地没有仓库代码,服务器全部是压缩的代码,我们要调试变得很困难,普通的做法就是下载服务器的压缩包到本地,通过 nginx 运行,进行本地调试,最后修改压缩包再重新部署到服务器。殊不知浏览器已经提供了 overrides 功能?
打開控制台
選擇原始碼,點擊替換

點擊+選擇一個文件夾(可以在桌面隨便創建一個文件)
點擊同意

刷新頁面
选择网络,选择要修改的文件(
css或js),右键选择:保存并覆盖

- 此時可以看到該遠程文件已經被下載到本地對應文件夾中

- 直接在文件中修改代碼,頁面會同步修改

修改完以後,直接保存
把本地文件重新部署到遠程伺服器即可。
以上就是本次給大家整理的各種調試能力,希望大家喜歡,我是河畔一角。