2022 年 6 月 26 日

在瀏覽器中偵錯

在撰寫更複雜的程式碼之前,我們來談談偵錯。

偵錯是找出並修正腳本中錯誤的過程。所有現代瀏覽器和大多數其他環境都支援偵錯工具,這是開發人員工具中的一種特殊使用者介面,可以讓偵錯變得容易許多。它也能逐行追蹤程式碼,查看實際上發生了什麼事。

我們將在此使用 Chrome,因為它有足夠的功能,大多數其他瀏覽器也有類似的流程。

「來源」面板

您的 Chrome 版本可能看起來有點不同,但仍然應該很明顯。

  • 在 Chrome 中開啟範例頁面
  • 使用 F12(Mac:Cmd+Opt+I)開啟開發人員工具。
  • 選取來源面板。

如果您是第一次這麼做,您應該會看到以下內容

切換按鈕 會開啟包含檔案的標籤頁。

讓我們按一下它,並在樹狀檢視中選取hello.js。以下為應該會顯示的內容

來源面板有 3 個部分

  1. 檔案瀏覽器窗格會列出 HTML、JavaScript、CSS 和其他檔案,包括附加到網頁的圖片。Chrome 擴充功能也可能會出現在這裡。
  2. 程式碼編輯器窗格會顯示原始碼。
  3. JavaScript 除錯窗格用於除錯,我們稍後會探討。

現在您可以再次按一下相同的切換器 ,以隱藏資源清單並為程式碼騰出一些空間。

主控台

如果我們按下 Esc,主控台會在下方開啟。我們可以在這裡輸入指令並按下 Enter 來執行。

陳述式執行後,其結果會顯示在下方。

例如,這裡的 1+2 結果為 3,而函式呼叫 hello("debugger") 沒有回傳任何值,因此結果為 undefined

中斷點

讓我們檢查一下 範例網頁 程式碼中的情況。在 hello.js 中,按一下第 4 行的號碼。是的,直接按一下 4 這個數字,而不是程式碼。

恭喜!您已設定中斷點。請也按一下第 8 行的號碼。

它應該看起來像這樣(藍色部分是您應該按一下的地方)

中斷點 是程式碼中除錯器會自動暫停 JavaScript 執行的點。

當程式碼暫停時,我們可以檢查目前的變數、在主控台中執行指令等。換句話說,我們可以除錯它。

我們可以在右邊的面板中隨時找到中斷點清單。當我們在不同的檔案中有許多中斷點時,這會很有用。它讓我們可以

  • 快速跳到程式碼中的中斷點(按一下右邊的面板中的中斷點即可)。
  • 暫時停用中斷點,方法是取消勾選它。
  • 按一下滑鼠右鍵,然後選取 [移除],即可移除中斷點。
  • …以此類推。
條件中斷點

按一下滑鼠右鍵 於行號上,即可建立一個條件中斷點。它只會在您建立時提供的特定表達式為真時觸發。

當我們只需要針對特定變數值或特定函式參數停止時,這會很方便。

「debugger」指令

我們也可以在程式碼中使用 debugger 指令暫停程式碼,如下所示

function hello(name) {
  let phrase = `Hello, ${name}!`;

  debugger;  // <-- the debugger stops here

  say(phrase);
}

此類指令僅在開發人員工具開啟時才會運作,否則瀏覽器會忽略它。

暫停並查看周圍

在我們的範例中,hello() 會在頁面載入期間呼叫,因此在設定中斷點後,最簡單的啟動除錯器方式就是重新載入頁面。因此,讓我們按下 F5(Windows、Linux)或 Cmd+R(Mac)。

由於已設定中斷點,執行會在第 4 行暫停

請開啟右側的資訊性下拉式選單(以箭頭標示)。它們讓您可以檢查目前的程式碼狀態

  1. 觀察 – 顯示任何表達式的目前值。

    您可以按一下加號 + 並輸入表達式。除錯器會顯示其值,並在執行過程中自動重新計算其值。

  2. 呼叫堆疊 – 顯示巢狀呼叫鏈。

    目前除錯器位於 hello() 呼叫內,由 index.html 中的腳本呼叫(那裡沒有函式,因此稱為「匿名」)。

    如果您按一下堆疊項目(例如「匿名」),除錯器會跳到對應的程式碼,且所有變數也可以檢查。

  3. 範圍 – 目前變數。

    區域 顯示區域函式變數。您也可以看到它們的值直接在來源上方以醒目方式標示。

    全域 有全域變數(在任何函式之外)。

    那裡也有 this 關鍵字,我們尚未研究,但我們很快就會研究。

追蹤執行

現在是追蹤腳本的時候了。

右側面板頂端有按鈕可以執行此動作。讓我們使用它們。

– 「繼續執行」:繼續執行,熱鍵 F8

繼續執行。如果沒有其他中斷點,則執行會繼續進行,而偵錯器會失去控制。

以下是我們點選它之後可以看到的內容

執行已繼續進行,已到達 say() 內部的另一個中斷點並在那裡暫停。查看右邊的「呼叫堆疊」。它已增加一個呼叫。我們現在位於 say() 內部。

– 「步驟」:執行下一個指令,熱鍵 F9

執行下一個陳述式。如果我們現在點選它,就會顯示 alert

一再點選它會逐一執行所有指令碼陳述式。

– 「跨步執行」:執行下一個指令,但不要進入函式,熱鍵 F10

類似於先前的「步驟」指令,但如果下一個陳述式是函式呼叫(不是內建函式,例如 alert,而是我們自己的函式),則行為會有所不同。

如果我們比較它們,「步驟」指令會進入巢狀函式呼叫,並在其第一行暫停執行,而「跨步執行」會在我們看不到的情況下執行巢狀函式呼叫,略過函式內部。

然後,執行會在該函式呼叫之後立即暫停。

如果我們對函式呼叫內部發生的事情不感興趣,這很好。

– 「逐步執行」,熱鍵 F11

這類似於「步驟」,但在非同步函式呼叫的情況下行為不同。如果你才剛開始學習 JavaScript,你可以忽略差異,因為我們還沒有非同步呼叫。

對於未來,請注意「步驟」指令會忽略稍後執行的非同步動作,例如 setTimeout(排定的函式呼叫)。「逐步執行」會進入其程式碼,必要時等待它們。有關更多詳細資訊,請參閱 DevTools 手冊

– 「跳出步驟」:繼續執行直到目前函式的結尾,熱鍵 Shift+F11

繼續執行並在目前函式的最後一行停止執行。當我們不小心使用 輸入巢狀呼叫,但我們對它不感興趣,而且我們想儘快繼續到它的結尾時,這很方便。

– 啟用/停用所有中斷點。

該按鈕不會移動執行。僅用於中斷點的整體開/關。

– 在發生錯誤時啟用/停用自動暫停。

啟用後,如果開發人員工具已開啟,腳本執行期間發生的錯誤會自動暫停執行。然後我們可以在偵錯器中分析變數,查看哪裡出錯。因此,如果我們的腳本因錯誤而中斷,我們可以開啟偵錯器,啟用此選項並重新載入頁面,以查看中斷位置及其當時的內容。

繼續到此處

右鍵按一下程式碼行會開啟內容功能表,其中有一個稱為「繼續到此處」的絕佳選項。

當我們想要向前移動多個步驟到該行時,但又懶得設定中斷點時,這會很方便。

記錄

若要從我們的程式碼輸出一些內容到主控台,可以使用 console.log 函數。

例如,這會將值從 0 輸出到 4 到主控台

// open console to see
for (let i = 0; i < 5; i++) {
  console.log("value,", i);
}

一般使用者看不到該輸出,它在主控台中。若要查看它,請開啟開發人員工具的主控台面板,或在另一個面板中按 Esc:這會在底部開啟主控台。

如果我們的程式碼中有足夠的記錄,那麼我們就可以從記錄中查看發生了什麼事,而不需要偵錯器。

摘要

正如我們所見,有三個主要方法可以暫停腳本

  1. 中斷點。
  2. debugger 陳述式。
  3. 錯誤(如果開發人員工具已開啟,且按鈕 為「開啟」)。

暫停時,我們可以進行偵錯:檢查變數並追蹤程式碼,以查看執行錯誤的地方。

開發人員工具中還有許多選項,這裡沒有涵蓋。完整的說明書位於 https://developers.google.com/web/tools/chrome-devtools

本章節中的資訊足以開始進行偵錯,但稍後,特別是如果您進行大量的瀏覽器操作時,請前往該處並查看開發人員工具的更進階功能。

喔,您也可以按一下開發人員工具的各個位置,並查看顯示的內容。這可能是學習開發人員工具最快的途徑。別忘了右鍵按一下和內容功能表!

教學地圖

註解

在評論之前先閱讀此內容…
  • 如果您有任何建議要改進 - 請 提交 GitHub 問題 或提交拉取請求,而不是評論。
  • 如果您無法理解文章中的某個部分,請詳細說明。
  • 若要插入幾行程式碼,請使用 <code> 標籤,若要插入多行程式碼,請將它們包覆在 <pre> 標籤中,若要插入超過 10 行程式碼,請使用沙盒 (plnkrjsbincodepen…)