概覽#

斷點讓程式碼暫停後,下一步就是控制執行流程,配合單步執行(Step Over / Step Into / Step Out)功能逐步觀察程式行為。在 Sources 面板進行 Debug 通常包含四個階段:

  • 重現問題:找出觸發 Bug 的操作流程。
  • 建立斷點:在合適的位置(搭配適合的斷點類型)讓程式碼停下來。
  • 控制執行:透過跳轉、單步執行控制程式碼的進行。
  • 檢查狀態:監看變數、調用堆疊(Call Stack),或在 Console 直接執行程式碼觀察。

執行控制#

執行控制就像一個程式碼播放器,提供暫停、繼續、跳到指定位置等操作。當程式碼暫停後,可以在程式碼任何位置按右鍵,選擇 Continue to Here 直接快轉到該行,跳過不感興趣的部分。等同於在那個位置設一個一次性斷點再按繼續。

逐步執行#

面板上方有多個箭頭圖示,名稱統一稱為單步執行(Step Over / Step Into / Step Out),但在不同情境下行為各異。

Step Over#

對即將執行的 Function 內部沒興趣時,Step Over 會跳過這個 Function 直接停在後一行。

以下方程式碼為例,假設目前停在 A 行的 double

const number = 3;
const result = double(number); // A
console.log(result); // D

function double(n) {
  const result = n * 2; // B
  return result; // C
}

按下 Step Over 後 double 內部會被執行完,最後停在 D 行的 console.log

Step Into#

當問題就在即將執行的 Function 裡,Step Into 會直接進入該 Function 的第一行。同樣以上面的程式碼為例,停在 A 行時按 Step Into 會跳到 B 行。

Step Out#

確認目前所在 Function 沒問題後,Step Out 會執行完剩下的程式碼並跳到 Function 結束之後的位置。如果停在 B 行,按 Step Out 會跳到 D 行。

非同步程式碼#

在同步程式碼中,Step Into 和 Step 行為幾乎完全相同。但碰到非同步程式時兩者開始有差異:

  • Step Into:跳過剩餘的同步程式碼,直接進入非同步 callback。
  • Step:只會停在下一行同步程式碼,不主動進入非同步部分。

以下程式碼直接執行時印出順序為 2、3、1,假設目前停在 A 行:

setTimeout(() => console.log(1), 2000); // A
console.log(2); // B
console.log(3); // C

按 Step Into 會在執行完 B、C 行後(因為要等 setTimeout 進入 callback)停在 callback 的第一行,中間需要等 2 秒。

按 Step 則會依序停在 B、C,再按一次才停到 callback。

多執行緒#

當程式涉及 Worker 時,Step Into 和 Step 同樣有差異。例如:

// index.js
new Worker("worker.js"); // A
console.log("Hello World!"); // B

// worker.js
console.log("Hello Worker!"); // W

假設停在 A 行:

  • 按 Step Into:直接打開 worker.js 並停在 W 行,這時 B 行已經被執行。
  • 按 Step:先停到 B 行,再按一次才會停到 W 行。

進入 Worker 後 Sources 面板右上角會看到多個 Thread,Console 面板的 Context 也會切到對應的 Worker。

暫時停用斷點#

若想要暫時關閉所有斷點,可以透過:

  • 右側 Breakpoints 列表的 Checkbox 個別開關。
  • 上方的 Deactivate breakpoints 一次關掉所有斷點。
  • 在程式碼行號右鍵選 Never pause here 來避免 debugger 關鍵字觸發暫停。

一行多個 Function#

如果一行裡有多個 Function 呼叫,可以分別在每個 Function 前下斷點:

function a() {
  console.log("a");
  return 1;
}
function b() {
  console.log("b");
  return 2;
}
console.log(a() + b());

未額外下斷點時,Step Over 會直接跳到下一行。要單獨停在 b 之前,可以:

  • b 前加一個斷點。
  • 或對 a 使用 Step Into 讓它執行完後停在 b 之前。

小結#

熟練 Step Over、Step Into、Step Out 之後,你可以像看影片一樣自由控制 JavaScript 的播放,這比依賴難以中斷又受限於參數內容的 console.log 強大很多。

下一章會繼續介紹 JavaScript Debugger 的其他功能,包括變數列表、調用堆疊與 Blackbox。

原文出處#