本文 AI 產出,尚未審核

JavaScript – 錯誤與除錯(Error Handling & Debugging)

主題:console.log / console.error


簡介

在 JavaScript 開發的過程中,除錯永遠是不可或缺的環節。即使是最簡單的程式,也可能因為變數未定義、型別不符或非同步流程的誤用而產生錯誤。若沒有適當的訊息輸出,開發者往往只能靠「猜測」與「靜默失敗」來定位問題,這不但浪費時間,也會降低程式的可維護性。

console 物件提供了多種方法讓我們 即時觀察程式執行狀態,其中最常用的就是 console.log(一般訊息)與 console.error(錯誤訊息)。透過正確的使用方式,我們可以在瀏覽器開發者工具或 Node.js 終端機上快速取得變數內容、流程走向,甚至在正式上線前就把潛在的錯誤先捕捉到。

本篇文章將從 概念實作範例常見陷阱與最佳實踐,再到 實務應用,完整說明如何善用 console.logconsole.error 來提升除錯效率,適合 初學者到中級開發者 閱讀與實踐。


核心概念

1. console 物件概覽

console 是瀏覽器與 Node.js 內建的全域物件,提供多種輸出方法:

方法 目的 特色
console.log() 輸出一般訊息 支援多參數、字串佔位、樣式
console.error() 輸出錯誤訊息 會以紅色文字(或 stderr)呈現
console.warn() 警告訊息 以黃色文字顯示
console.table() 表格化資料 方便檢視陣列或物件集合
console.group() / console.groupEnd() 分組顯示 讓訊息層次更清晰
console.time() / console.timeEnd() 計時 測量程式碼執行時間

在本篇重點聚焦於 console.logconsole.error,但了解其他方法有助於建立完整的除錯工具箱。


2. console.log 的基本用法

  • 單一參數:直接印出字串、數字、布林或物件。
  • 多參數:以逗號分隔,可同時顯示多個值。
  • 字串佔位:使用 %s(字串)、%d(數字)、%o(物件)等佔位符,讓訊息更具可讀性。
  • 樣式:在瀏覽器開發者工具中,可透過 %c 加上 CSS 樣式,改變文字顏色、字型等。
// 單一參數
console.log('Hello, World!');

// 多參數
const name = 'Alice';
const age = 28;
console.log('使用者資訊:', name, age);

// 字串佔位
console.log('使用者 %s 的年齡是 %d 歲', name, age);

// 加樣式(僅在瀏覽器有效)
console.log('%c重要訊息:%c 這是一段紅字', 'color: blue; font-weight: bold;', 'color: red;');

3. console.error 的使用時機

console.error 會把訊息送到 錯誤輸出流(stderr),在瀏覽器裡會以紅色字體呈現,在 Node.js 中則會寫入 process.stderr。適合在以下情況使用:

  • 捕捉例外(try...catch)後的錯誤資訊。
  • 手動拋出自訂錯誤訊息,提醒開發者或測試人員。
  • 在測試環境中標示失敗的測試案例。
function divide(a, b) {
  if (b === 0) {
    console.error('除數不能為 0!', { a, b });
    return NaN;
  }
  return a / b;
}

divide(10, 0);

4. 進階技巧:使用 console.group 讓訊息層次分明

在除錯較大型的程式時,訊息往往會堆疊成一長串,難以快速定位。console.group() 可以把相關訊息「收合」起來,點擊展開即可查看。

function fetchUser(id) {
  console.group(`📦 fetchUser(${id})`);
  console.log('開始請求...');
  // 假設此處有非同步呼叫
  setTimeout(() => {
    console.log('收到回應:', { id, name: 'Bob' });
    console.groupEnd();
  }, 500);
}

fetchUser(123);

5. 透過 console.table 檢視陣列或物件集合

當需要觀察大量資料時,console.table 能把陣列或物件以表格形式展示,讓欄位與列的對應更直觀。

const users = [
  { id: 1, name: 'Amy', age: 24 },
  { id: 2, name: 'Ben', age: 30 },
  { id: 3, name: 'Cindy', age: 27 },
];

console.table(users);

程式碼範例(實用示例 5 個)

範例 1:基本除錯 – 變數檢查

function calculateTotal(price, quantity) {
  console.log('price:', price, 'quantity:', quantity); // 觀察輸入值
  return price * quantity;
}

calculateTotal(120, 3);

範例 2:使用佔位與樣式提升可讀性

const apiUrl = 'https://api.example.com';
const method = 'GET';
console.log('%c[API] %s %s', 'color: teal; font-weight: bold;', method, apiUrl);

範例 3:捕捉例外並輸出錯誤訊息

try {
  JSON.parse('this is not JSON');
} catch (e) {
  console.error('JSON 解析失敗!', e);
}

範例 4:分組顯示非同步流程

async function loadData() {
  console.group('🔄 loadData');
  console.log('開始載入…');

  const res = await fetch('https://jsonplaceholder.typicode.com/posts/1');
  const data = await res.json();

  console.log('取得資料:', data);
  console.groupEnd();
}

loadData();

範例 5:表格化 API 回傳資料

fetch('https://jsonplaceholder.typicode.com/users')
  .then(r => r.json())
  .then(users => {
    console.table(users.map(u => ({
      ID: u.id,
      姓名: u.name,
      電子郵件: u.email,
      城市: u.address.city,
    })));
  })
  .catch(err => console.error('取得使用者失敗', err));

常見陷阱與最佳實踐

陷阱 說明 解決方式
忘記移除 console.log 上線前留下大量除錯訊息會影響效能與安全性。 使用 Lint(如 ESLint)設定 no-console 規則,或在建置流程中自動移除。
錯誤訊息與一般訊息混用 console.logconsole.error 混在一起,難以分辨真正的錯誤。 分層輸出:錯誤使用 console.error,資訊使用 console.logconsole.warn
過度印出大型物件 印出過大的陣列或物件會卡住開發者工具。 使用 console.tableJSON.stringify(obj, null, 2) 或只印出關鍵屬性。
在生產環境直接顯示機密資訊 把 API 金鑰、密碼等資訊寫入 console.log,會被使用者看到。 永遠不要在除錯訊息中暴露機密資訊;使用環境變數與條件編譯。
缺少上下文說明 單純印出變數值,無法快速了解它屬於哪個流程。 加上 標籤分組 (console.group) 來提供上下文。

最佳實踐清單

  1. 區分訊息等級loginfowarnerror 各司其職。
  2. 使用佔位符與樣式:讓訊息在視覺上更突出。
  3. 在非同步程式中加入分組:方便追蹤 Promise、async/await 的執行順序。
  4. 結合 Lint 工具自動偵測:在 CI 流程中確保不會遺漏除錯訊息。
  5. 針對不同環境設定輸出:開發環境保留完整除錯資訊,上線環境僅保留必要的錯誤報告。

實際應用場景

1. 前端 UI 開發:追蹤使用者互動

在開發表單驗證或 UI 動畫時,常需要即時觀察事件參數。使用 console.log 搭配 event 物件,可快速確認觸發條件。

document.getElementById('submitBtn').addEventListener('click', e => {
  console.log('按鈕被點擊 - 事件資訊:', e);
});

2. API 串接:偵測錯誤回應

當前端向後端發送請求時,若回傳錯誤代碼,使用 console.error 能在開發者工具中立即提示。

fetch('/api/orders')
  .then(r => {
    if (!r.ok) {
      console.error('API 錯誤!狀態碼:', r.status);
      throw new Error('Network response was not ok');
    }
    return r.json();
  })
  .then(data => console.log('訂單資料:', data))
  .catch(err => console.error('取得訂單失敗', err));

3. Node.js 後端服務:記錄錯誤與效能

在伺服器端,我們可以把 console.error 的訊息導向日誌檔,配合 process.on('uncaughtException') 捕捉未處理的例外。

process.on('uncaughtException', err => {
  console.error('未捕捉的例外:', err);
  // 可在此寫入外部日誌系統
  process.exit(1);
});

4. 單元測試:顯示失敗原因

使用測試框架(如 Jest)時,若測試失敗,console.error 能把錯誤資訊直接呈現在測試報告中,協助定位問題。

test('divide 函式應拋出錯誤', () => {
  expect(() => divide(5, 0)).toThrow();
  console.error('測試中發現除以 0 的情況已正確處理');
});

總結

  • console.logconsole.error除錯的第一線工具,善加利用能大幅提升開發效率。
  • 透過 佔位符、樣式、分組、表格化 等技巧,我們可以把訊息變得更有條理、更易讀。
  • 注意 訊息等級的區分避免洩漏機密在上線前清除不必要的除錯輸出,才能保持程式的安全與效能。
  • 結合 Lint、CI環境條件,讓除錯流程自動化、標準化,進一步降低人為疏失。

掌握這些概念後,你將能在開發過程中 快速定位錯誤、洞悉執行流程,為後續的功能擴充與維護奠定堅實基礎。祝你在 JavaScript 的世界裡除錯無礙、開發順利!