別再 console.log 了:5 個 Chrome DevTools 除錯技巧,用過就回不去了

> 我觀察過身邊的前端同事,90% 的人除錯程式碼的方式就是一行行加 `console.log`。改完了再一行行刪。出 bug 再加回來。這個循環我自己也幹了兩年,直到有一天我發現了 Chrome DevTools 裡這些「隱藏」功能——說是隱藏,其實一直都在那,只是沒人告訴你怎麼用。這篇文章把 5 個最實用的技巧寫出來,每個都附操作步驟,看完今天就能用上。

為什麼你應該少用 console.log

先說清楚:console.log 不是不能用。但它有三個致命問題:

  1. 侵入式:你得改程式碼、儲存、重新整理頁面、看輸出、再改程式碼、再刪掉。一個 bug 可能要加刪十幾次。
  2. 資訊有限:它只能告訴你「某個值是什麼」,不能告訴你「這個值是從哪來的」、「呼叫堆疊是什麼」、「經歷了哪些狀態變化」。
  3. 忘記刪的風險:線上程式碼裡夾著 console.log('test')console.log('到這了'),你一定在別人的專案裡見過。

DevTools 的除錯工具可以做到 console.log 做不到的事,而且不需要改任何一行程式碼


技巧 1:條件中斷點 — 取代 if (id === 5) console.log(data)

場景

你有一個列表渲染了 100 筆資料,但只有第 5 筆資料有 bug。用 console.log 的話,要嘛印 100 筆慢慢找,要嘛加 if 判斷:

javascript 代碼解讀複製代碼// 你以前的做法
items.forEach(item => {
  if (item.id === 5) {
    console.log('有問題的資料:', item);
  }
  renderItem(item);
});

用條件中斷點

  1. 打開 DevTools → Sources 面板
  2. 找到對應程式碼,在行號上右鍵 → 選擇 Add conditional breakpoint
  3. 輸入條件:item.id === 5
  4. 按 Enter 確認

現在程式碼只會在 item.id === 5 時暫停,你可以在 Scope 面板裡直接看到 item 的所有屬性,不需要改任何程式碼。

進階用法: 條件表示式裡可以寫任何 JS,包括:

javascript 代碼解讀複製代碼// 只在陣列長度異常時斷住
arr.length > 100

// 只在某個屬性為 null 時斷住
user.profile === null

// 組合條件
item.status === 'error' && item.retryCount > 3

中斷點的顏色會變成橘色(普通中斷點是藍色),方便你區分。


技巧 2:Logpoint — 不改程式碼就能打日誌

場景

你想在某行程式碼執行時列印一些資訊,但不想改程式碼(比如程式碼在 node_modules 裡,或者你不想頻繁儲存觸發熱更新)。

操作步驟

  1. Sources 面板,在行號上右鍵 → 選擇 Add logpoint
  2. 輸入要列印的內容,語法和 console.log 一樣:
javascript 代碼解讀複製代碼'使用者資料:', user, '請求耗時:', Date.now() - startTime, 'ms'
  1. 按 Enter 確認,行號旁邊會出現一個粉紅色菱形標記

程式碼執行到這一行時,會在 Console 面板輸出你寫的內容,但不會暫停執行

和 console.log 的差別

對比項console.logLogpoint需要改程式碼是否需要儲存重新整理是否除錯完要刪掉是關掉 DevTools 自動消失在 node_modules 裡能用不方便可以這是我用得最多的功能。 團隊裡有個同事之前遇到第三方函式庫的 bug,加了 20 行 console.lognode_modules 裡,調完了忘刪,下一次 npm install 覆蓋掉了他的除錯程式碼,他又加了一遍。如果用 Logpoint,根本不需要碰原始碼。


技巧 3:Console 進階 API — 取代滿屏的 console.log

大多數人只知道 console.log。但 Console API 還有這些:

console.table() — 表格展示資料

javascript 代碼解讀複製代碼const users = [
  { id: 1, name: '張三', role: 'admin', active: true },
  { id: 2, name: '李四', role: 'user', active: false },
  { id: 3, name: '王五', role: 'user', active: true },
];

// 之前:console.log(users)  → 輸出一坨摺疊的物件

// 現在:
console.table(users);

輸出會是一個整齊的表格,欄頭是屬性名,一目了然。還可以指定只顯示某些欄位:

javascript 代碼解讀複製代碼console.table(users, ['name', 'role']);

console.group() — 分組摺疊

javascript 代碼解讀複製代碼console.group('使用者請求流程');
console.log('1. 送出請求');
console.log('2. 收到回應', response);
console.log('3. 更新狀態');
console.groupEnd();

console.group('渲染流程');
console.log('1. 計算 diff');
console.log('2. 更新 DOM');
console.groupEnd();

輸出會按組摺疊,不再是一大坨混在一起的日誌。用 console.groupCollapsed() 還能預設摺疊。

console.time() — 精確計時

javascript 代碼解讀複製代碼console.time('資料處理');
const result = processLargeDataset(rawData);
console.timeEnd('資料處理');
// 輸出:資料處理: 142.38ms

Date.now() 相減更精確,而且不需要建立暫時變數。

console.trace() — 列印呼叫堆疊

javascript 代碼解讀複製代碼function updateUser(id, data) {
  console.trace('updateUser 被誰呼叫了');
  // ...
}

輸出完整的呼叫鏈,直接告訴你這個函式是從哪個路徑進來的。排查「這個函式怎麼被呼叫了兩次」的問題特別好用。

console.assert() — 條件日誌

javascript 代碼解讀複製代碼console.assert(user.age > 0, '年齡不應該小於等於 0', user);

只有條件為 false 時才輸出,取代 if (!xxx) console.log()


技巧 4:Network Override — 不改後端程式碼除錯介面

場景

後端介面回傳的資料有問題,你想暫時改一下回傳值來測試前端邏輯。以前你可能會:

  • 找後端同事幫忙改介面(等半天)
  • 在前端程式碼裡硬編碼 mock 資料(改完還得刪)
  • 用 Charles/Whistle 抓包改回應(設定麻煩)

用 Network Override

  1. DevTools → Network 面板
  2. 找到目標請求,右鍵 → 選擇 Override content
  3. DevTools 會讓你選一個本機資料夾作為 override 目錄
  4. 修改回應內容,儲存

之後每次重新整理頁面,這個介面都會回傳你修改後的內容,不需要改任何前端或後端程式碼

實際案例

後端介面 /api/users 回傳了 10 筆資料,但你要測試「空列表」狀態:

  1. 正常請求一次,Override content
  2. 把回應本文改成 []
  3. 重新整理頁面,前端就會渲染空狀態

要測試「超長資料」?把回應改成 1000 筆資料。要測試「欄位缺失」?刪掉某個欄位。

進階:Override Headers

不只是回應本文,你還可以 Override 回應標頭:

  • 模擬 CORS 錯誤:刪掉 Access-Control-Allow-Origin 標頭
  • 模擬快取策略:修改 Cache-Control 標頭
  • 模擬慢網路:在 Network 面板頂部的 Throttling 選項裡選 Slow 3G

技巧 5:Live Expressions — 即時監控變數

場景

你想持續觀察某個變數的值變化,用 console.log 的話,每次值變化都要重新列印,Console 面板很快就被刷屏了。

操作步驟

  1. DevTools → Console 面板
  2. 點擊 Console 面板頂部的眼睛圖示(Create live expression)
  3. 輸入你要監控的表示式:
javascript 代碼解讀複製代碼document.querySelectorAll('.list-item').length
  1. 這個表示式的值會即時更新,不需要你手動執行

常用監控表示式

javascript 代碼解讀複製代碼// 監控頁面上有多少 DOM 節點
document.querySelectorAll('*').length

// 監控某個全域狀態
window.__STORE__.getState().user.loginStatus

// 監控頁面捲動位置
Math.round(window.scrollY)

// 監控記憶體使用
(performance.memory.usedJSHeapSize / 1048576).toFixed(1) + 'MB'

你可以同時新增多個 Live Expression,相當於一個即時儀表板,比反覆 console.log 高效得多。


總結:場景對照表

除錯場景console.log 做法DevTools 做法查看某個變數值加 console.log(x)條件中斷點,在 Scope 面板看在某行列印日誌改程式碼加 logLogpoint,不改程式碼列印陣列/物件console.log(arr)``console.table(arr)分組列印手動加分隔符console.group()計算耗時Date.now() 相減console.time()查看呼叫堆疊猜console.trace()修改介面回傳值Mock 或找後端Network Override即時監控變數setInterval + logLive Expression除錯 node_modules改原始碼(危險)Logpoint 或條件中斷點---

一個實際 debug 故事

上個月我們專案有個 bug:列表頁的分頁元件在第 3 頁之後會顯示錯誤的總數。

如果用 console.log 除錯,我得:

  1. 在分頁元件裡加 log,列印 total 值 → 值是對的
  2. 在請求函式裡加 log,列印回應資料 → 資料也是對的
  3. 在狀態管理裡加 log,列印 store → 也是對的
  4. 困惑,加更多 log...

我實際的做法:

  1. Network Override 把第 3 頁的介面回應 total 改成一個特殊值(比如 999)
  2. 頁面顯示 999 → 代表元件渲染邏輯沒問題,資料能正確傳到 UI
  3. 拿掉 Override,用 條件中斷點 在狀態更新的地方設 page === 3 的條件
  4. 斷住後在 Scope 面板發現:第 3 頁請求回來時,有一個競態條件——第 2 頁的請求比第 3 頁晚到達,把 total 覆蓋成了第 2 頁的值

從發現 bug 到定位根因:12 分鐘。 如果用 console.log 大法,光加 log 刪 log 就得半小時。


快捷鍵速查

操作MacWindows打開 DevToolsCmd + Option + I``F12打開 Command MenuCmd + Shift + P``Ctrl + Shift + P搜尋檔案Cmd + P``Ctrl + P搜尋程式碼Cmd + Option + F``Ctrl + Shift + F切換面板Cmd + ] / Cmd + [``Ctrl + ] / Ctrl + [暫停/繼續執行F8``F8單步執行F10``F10進入函式F11``F11在 Command Menu(Cmd + Shift + P)裡輸入 "logpoint" 或 "override" 可以快速找到對應功能。


如果對你有幫助,按讚收藏一下。這些技巧我自己每天都在用,確實比 console.log 效率高很多。如果你有其他 DevTools 的隱藏技巧,留言區分享一下。


原文出處:https://juejin.cn/post/7654473428947795994


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝14   💬2   ❤️1
746
🥈
我愛JS
📝1   ❤️1
68
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登