本文 AI 產出,尚未審核

JavaScript 錯誤與除錯:深入了解 debugger 語句


簡介

在日常的 JavaScript 開發過程中,錯誤與除錯 是不可避免的挑戰。即使是最有經驗的開發者,也會因為程式邏輯錯誤、非同步流程或瀏覽器相容性問題而卡關。若只能靠 console.log 逐行印出變數,就像在黑暗的房間裡用手電筒找東西,雖然能看到一點光,但往往不夠精確、效率也不高。

debugger 語句正是為了彌補這個缺口而設計的。它可以 在程式執行到特定位置時,主動觸發瀏覽器的除錯工具,讓開發者即時停下程式、檢查執行環境、觀察變數值,甚至一步一步「單步執行」程式碼。掌握 debugger 的使用時機與技巧,能大幅提升除錯效率,減少因為找錯誤而浪費的開發時間。

本篇文章將從 概念、實作範例、常見陷阱與最佳實踐 三個層面,帶你完整了解 debugger 的功能與應用,並提供實務上的使用情境,幫助你在日常開發中更從容地面對錯誤。


核心概念

1. debugger 是什麼?

debugger 是 JavaScript 的一個保留關鍵字,當執行到這一行時,若瀏覽器的開發者工具(DevTools)已開啟且支援除錯,程式會自動暫停。此時,你可以:

  • 查看呼叫堆疊(Call Stack)
  • 檢查當前作用域(Scope)中的變數值
  • 觀察物件的屬性與原型鏈
  • 使用「步入(Step Into)」、「步過(Step Over)」、「步出(Step Out)」等指令逐行執行

注意:如果開發者工具沒開啟,debugger 會被視為普通的空語句,程式不會中斷。

2. 為什麼要使用 debugger 而不是只靠 console.log

方式 優點 缺點
console.log 快速、簡單、可在正式環境留下日誌(若需要) 需要手動插入/移除,訊息量大時難以追蹤;無法即時觀察呼叫堆疊
debugger 直接切入除錯介面,可即時檢查所有變數與執行流程 必須在開發時開啟 DevTools;若忘記移除,會在正式環境中觸發暫停(不建議上線)

3. debugger 的語法

debugger; // 單獨使用

它本身不返回值,也不接受參數。只要這行程式碼被執行,除錯器就會介入


程式碼範例

下面提供 5 個實用的範例,展示 debugger 在不同情境下的應用方式。每段程式碼都附有註解,說明為何以及如何使用 debugger

範例 1:基本使用 – 停在函式入口

function calculateArea(radius) {
    // ★ 在函式進入點下斷點,檢查傳入的參數
    debugger;
    const pi = Math.PI;
    return pi * radius * radius;
}

calculateArea(5);

說明:當 calculateArea 被呼叫時,程式會在 debugger 那一行暫停。開發者可以在 DevTools 中檢查 radius 的實際值,確保傳入的參數正確。


範例 2:非同步流程 – 配合 async/await

async function fetchUser(id) {
    const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
    // ★ 在取得回應後暫停,觀察 response 物件
    debugger;
    const data = await response.json();
    return data;
}

fetchUser(3);

說明:非同步程式碼往往較難追蹤,尤其是 await 前後的執行順序。將 debugger 放在 await 之後,可讓你檢查 response 是否成功,或觀察 HTTP 狀態碼。


範例 3:條件斷點 – 只在特定情況下停下

function findPrime(limit) {
    for (let i = 2; i <= limit; i++) {
        let isPrime = true;
        for (let j = 2; j * j <= i; j++) {
            if (i % j === 0) {
                isPrime = false;
                break;
            }
        }
        // ★ 只在找到 97 時暫停
        if (i === 97) debugger;
        if (isPrime) console.log(i);
    }
}

findPrime(100);

說明:在大量迴圈中,我們不想每次都停下,只在特定條件(如 i === 97)時觸發斷點。這樣可以快速定位「為什麼這個數字」的相關資訊。


範例 4:搭配 try…catch 捕捉例外

function parseJSON(jsonStr) {
    try {
        const obj = JSON.parse(jsonStr);
        return obj;
    } catch (error) {
        // ★ 在例外發生時暫停,查看錯誤資訊與原始字串
        debugger;
        console.error('JSON 解析失敗:', error);
        return null;
    }
}

// 故意傳入錯誤的 JSON
parseJSON('{"name": "Alice", age: 30}');

說明:例外處理是除錯的重要環節。將 debugger 放在 catch 區塊,可立即檢視錯誤物件與導致錯誤的原始資料,協助快速定位問題根源。


範例 5:在框架(如 React)中使用 debugger

import React, { useState, useEffect } from 'react';

function Counter() {
    const [count, setCount] = useState(0);

    useEffect(() => {
        // ★ 每次 count 更新後暫停,檢查最新值
        debugger;
        console.log('Count updated:', count);
    }, [count]);

    return (
        <button onClick={() => setCount(count + 1)}>
            點擊次數:{count}
        </button>
    );
}

說明:在 React 的 Hook 中,useEffect 會在依賴變更時執行。將 debugger 放在 useEffect 內,可觀察每次渲染後的狀態,對於追蹤 UI 更新非常有幫助。


常見陷阱與最佳實踐

1. 忘記移除 debugger

在正式上線前,務必搜尋整個專案,確保沒有遺留的 debugger。若不小心留下,使用者開發者工具開啟時會直接卡在斷點,影響使用體驗。

2. 在大量迴圈中濫用 debugger

在高頻率執行的迴圈裡插入 debugger,會導致瀏覽器頻繁暫停,極度拖慢除錯流程。建議改用 條件斷點if (cond) debugger; 的方式,限制觸發次數。

3. 依賴 debugger 取代單元測試

debugger 是除錯工具,不是測試工具。仍需撰寫單元測試、整合測試,以自動化驗證程式正確性。

4. 在生產環境的第三方腳本中使用 debugger

若你的程式碼會被第三方載入(如 CDN、廣告腳本),不建議在這些檔案中放置 debugger,以免影響其他網站的執行。

5. 最佳實踐清單

項目 建議做法
斷點位置 debugger 放在 最可能出錯的地方(參數驗證、API 回應、例外捕捉)
條件斷點 使用 if (condition) debugger; 以避免過度暫停
移除機制 在 CI/CD 流程加入 lint 規則(如 ESLint no-debugger
說明註解 debugger 前加上簡短說明,提醒同事斷點目的
開發環境 僅在 本機或測試環境 使用,正式環境禁用

實際應用場景

1. API 整合除錯

當前端呼叫後端 API,回傳資料結構不如預期時,常見的做法是:

fetch('/api/user')
    .then(res => res.json())
    .then(data => {
        // 觀察資料結構
        debugger;
        renderUser(data);
    })
    .catch(err => console.error(err));

透過 debugger,開發者能立即檢查 data 物件的屬性與型別,避免因為資料格式變動而導致 UI 錯亂。

2. 性能瓶頸定位

在大量資料處理或動畫渲染時,使用 debugger 結合 Performance 面板,可快速定位哪段程式碼耗時過長。例如:

function heavyComputation(arr) {
    debugger; // 暫停前檢查傳入陣列長度
    // ... 計算過程
}

在 DevTools 的「Performance」中點擊「Pause」後,直接跳到此斷點,觀察變數與呼叫堆疊,找出效能瓶頸。

3. 跨瀏覽器相容性測試

不同瀏覽器的 JavaScript 引擎行為略有差異。利用 debugger,可以在 Safari、Chrome、Edge 等瀏覽器中逐一測試同一段程式碼,確保行為一致。

4. 教學與面試

在教學或技術面試時,即時示範 debugger 能讓受眾清楚看到變數變化、執行流程,提升教學效果。面試官也常用 debugger 觀察候選人除錯思路。


總結

  • debugger 是 JavaScript 內建的除錯關鍵字,能在程式執行到指定位置時自動暫停,讓開發者即時檢查變數、呼叫堆疊與執行環境。
  • 相較於 console.logdebugger 提供更直觀、即時的除錯體驗,尤其在 非同步流程、例外處理與框架 Hook 中顯得格外有價值。
  • 使用時需注意 不要在正式環境遺留,避免過度在迴圈中斷,並結合 條件斷點Lint 規則 來保持程式碼品質。
  • 透過上述範例與最佳實踐,你可以在 API 整合、效能優化、跨瀏覽器測試等多種實務情境中,快速定位問題、縮短除錯時間。

掌握 debugger 的技巧,就是讓你的 JavaScript 開發更高效、可靠的關鍵一步。祝你在除錯的旅程中,從此不再「盲目摸索」而是「精準定位」! 🚀