
作為一名程式設計師,就算你擁有孫悟空的 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 格式複製)
- 在主控台界面,貼上
- 修改請求參數,直接按 Enter 即可
- 複製請求

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

- 按 Enter 傳送請求

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),右鍵選擇:儲存並覆蓋

- 此時可以看到該遠端檔案已經被下載到本地對應資料夾中

- 直接在檔案中修改程式碼,頁面會同步修改

修改完以後,直接儲存
把本地檔案重新部署到遠端伺服器即可。
以上就是本次給大家整理的各種除錯能力,希望大家喜歡,我是河畔一角。