在Chrome DevTools中除錯JavaScript的實現
由淺入深說一說怎麼樣在 Chrome DevTools 中除錯 JavaScript。
一、案發現場
為了方便理解,我寫了一個小demo。
點選開啟demo;
在num1中輸入6;
在num2中輸入9;
點選 num1+num2,按鈕下方的標籤顯示 69,結果應為 15,這就是我們需要斷點除錯找出的 BUG 。
二、熟悉一下 Sources 面板
DevTools 可為更改 CSS、分析頁面載入效能和監控網路請求等不同的任務提供許多不同的工具。 我們就在 Sources 面板中除錯 JavaScript。
通過按 Command+Option+I
(Mac) 或 Control+Shift+I
Sources 面板包含 3 個部分:
檔案預覽 視窗。 此處列出頁面請求的每個檔案。
程式碼編輯 視窗。 在 檔案預覽 視窗中選擇檔案後,此處會顯示該檔案的具體內容。
JavaScript 除錯 視窗。 包含檢查頁面 JavaScript 的各種工具。 如果 DevTools 窗口布局較窄,此視窗會顯示在 程式碼編輯 視窗下方。
三、使用斷點暫停程式碼
除錯上面這種問題的常用方法是將多個 console.log()
語句插入程式碼,以便在執行指令碼的時候檢查相關變數的值。
雖然 console.log()
方法可以完成任務,但斷點可以更快完成此任務。 斷點可在執行程式碼的過程中暫停程式碼,並在此時及時檢查所有相關變數的值。 與 console.log()
方法相比,斷點具有一些優勢:
- 使用
console.log()
,需要手動開啟原始碼,查詢相關程式碼,插入console.log()
語句,然後重新載入此頁面,才能在控制檯中看到這些訊息。 使用斷點,無需瞭解程式碼結構即可暫停相關程式碼。 - 在
console.log()
語句中,您需要明確指定要檢查的每個值。 使用斷點,DevTools 會在暫停時及時顯示所有變數值。簡言之,與console.log()
接下來我們開始思考一開始丟擲的程式的運作方式,我們可以根據經驗推測出,我們在點選num1+num2按鈕的時候觸發的 click 事件肯定和 6+9=69 計算不正確有關係。 因此,我們可能需要在 click 偵聽器執行的時候暫停程式碼。
Event Listener Breakpoints
可以完成此任務:
在 JavaScript 除錯 視窗中,點選 Event Listener Breakpoints
前面的展開按鈕。 可以看見 Animation、Canvas、Clipboard 等一系列事件;
在頁面輸入框中輸入num1和num2的值;
展開 Mouse 事件,每個事件旁都有一個複選框。勾選 click 複選框。 DevTools 現在可以在任何 click 事件偵聽器執行時自動暫停。
點選頁面中的num1+num2按鈕。此時頁面如下圖:
這是因為我裝的瀏覽器外掛導致的定位不準,最好在無痕模式進行操作。不過也不影響,我們點選一下最左邊頁面上的藍色按鈕,再點選中間的打括號(格式化程式碼),就可以定位準確並且格式化好程式碼:
四、檢查變數的值
1. Scope視窗
在某程式碼行暫停時,Scope 窗格會顯示當前定義的區域性和全域性變數,以及各變數值。 其中還會顯示閉包變數(如果適用)。 雙擊變數值可進行編輯。 如果不在任何程式碼行暫停,則 Scope 窗格為空。
2. Watch監聽變數變化
Watch 標籤可監視變數值隨時間變化的情況。 並且,監視不僅限於監視變數。 我們可以將任何有效的 JavaScript 表示式儲存在監視表示式中。 我們嘗試這樣:
- 點選 Watch 標籤。
- 點選 右邊的 + 新增表示式。
- 輸入 typeof n
。 按 Enter 鍵。(這裡程式碼是打包後的,n表示num1輸入框的值)
- DevTools 會顯示 typeof n: "string"
。 冒號右側的值就是監視表示式的結果。
3. 控制檯
控制檯除了檢視 console.log()
訊息以外,還可以使用控制檯對任意 JavaScript 語句求值。 對於除錯,可以使用控制檯測試 BUG 的潛在解決方法:
在 Console 中,輸入 `parseInt(n) + parseInt(u)`。 此語句有效,因為我們會在特定程式碼行暫停,其中 `n`(num1的值) 和 `u`(num2的值) 在範圍內。
按 Enter 鍵。 DevTools 對語句求值並列印輸出 15,即我們預計demo頁面會產生的結果。
五、嘗試修改
上一步我們已找到解決 BUG 的方法。 接下來就是嘗試通過編輯程式碼並重新執行demo來使用修正方法。 我們可以在 程式碼編輯 視窗直接修改程式碼:
在 程式碼編輯 視窗中,將程式碼格式化關掉,然後修改程式碼,將 n+u
換成 parseInt(n)+parseInt(u)
。
按 Command+S
(Mac) 或 Control+S
(Windows、Linux)以儲存更改。
點選 Deactivate breakpoints 取消啟用斷點。 其將變為藍色,表示處於活動狀態。 在完成此設定後,DevTools 會忽略您已設定的任何斷點。
點選num1+num2按鈕,則會看見正確的結果啦!
Tips: 這樣做只能修正在瀏覽器中執行的程式碼, 不能為訪問您頁面的所有使用者修正程式碼。 為此,我需要修改自己伺服器上的程式碼。
六、介紹其他幾種斷點
斷點型別 | 使用場景 |
---|---|
程式碼行 | 在確切的程式碼區域中 |
條件程式碼行 | 在確切的程式碼區域中,且僅當其他一些條件成立時 |
DOM | 在更改或移除特定 DOM 節點或其子級的程式碼中 |
XHR | 當 XHR 網址包含字串模式時 |
事件偵聽器 | 在觸發 click 等事件後執行的程式碼中 |
異常 | 在引發已捕獲或未捕獲異常的程式碼行中 |
函式 | 任何時候呼叫特定函式時 |
1. 程式碼行斷點
直接點選
這是使用最多的一種斷點方式,在知道需要檢查的確切程式碼區域時,可以使用程式碼行斷點。 DevTools 始終會在執行此程式碼行之前暫停。
debugger
在程式碼中呼叫 debugger
可在該行暫停。 此操作相當於使用程式碼行斷點,只是此斷點是在程式碼中設定,而不是在 DevTools 介面中設定。
console.log('a'); console.log('b'); debugger; console.log('c');
條件程式碼斷點
如果知道需要調查的確切程式碼區域,但只想在其他一些條件成立時進行暫停,則可使用條件程式碼行斷點。若要設定條件程式碼行斷點:
- 點選 Sources 標籤。
- 開啟包含您想要中斷的程式碼行的檔案。
- 轉至程式碼行。
- 程式碼行的左側是行號列。
- 右鍵點選行號列。
- 選擇 Add conditional breakpoint。
- 程式碼行下方將顯示一個對話方塊。
- 在對話方塊中輸入條件。
- 按Enter 鍵啟用斷點。 行號列頂部將顯示一個橙色圖示。
2. DOM更新斷點
如果想要暫停更改 DOM 節點或其子級的程式碼,可以使用 DOM 更改斷點。若要設定 DOM 更改斷點:
- 點選 Elements 標籤。
- 轉至要設定斷點的元素。
- 右鍵點選此元素。
- 將滑鼠指標懸停在Break on 上,然後選擇 Subtree modifications、Attribute modifications 或 Node removal。
Subtree
- modifications: 在移除或添加當前所選節點的子級,或更改子級內容時觸發這類斷點。在子級節點屬性發生變化或對當前所選節點進行任何更改時不會觸發這類斷點。
- Attributes modifications:在當前所選節點上新增或移除屬性,或屬性值發生變化時觸發這類斷點。
- Node Removal:在移除當前選定的節點時會觸發。
4. XHR/Fetch斷點
如果想在 XHR 的請求網址包含指定字串時中斷,可以使用 XHR 斷點。 DevTools 會在 XHR 呼叫 send()
的程式碼行暫停。
注:此功能還可用於 Fetch 請求。
例如,在您發現您的頁面請求的是錯誤網址,並且您想要快速找到導致錯誤請求的 AJAX 或 Fetch 原始碼時,這類斷點很有用。
若要設定 XHR 斷點:
- 點選 Sources 標籤。
- 展開 XHR Breakpoints 窗格。
- 點選 Add breakpoint。
- 輸入要對其設定斷點的字串。 DevTools 會在 XHR 的請求網址的任意位置顯示此字串時暫停。
- 按 Enter 鍵以確認。
這樣就可以攔截包含getUserInfo
字串的請求,如果新增一個空的,則可以攔截所有請求!
5. 事件偵聽器斷點
如果想要暫停觸發事件後執行的事件偵聽器程式碼,可以使用事件偵聽器斷點。 您可以選擇 click 等特定事件或所有滑鼠事件等事件類別。
我們一開始使用的例子就是事件偵聽器斷點,這裡就不演示了。
6. 異常斷點
如果想要在引發已捕獲或未捕獲異常的程式碼行暫停,可以使用異常斷點。
- 點選 Sources 標籤。
- 點選 Pause on exceptions 引發異常時暫停 {:.devtools-inline}。 啟用後,此按鈕變為藍色。
- (可選)如果除未捕獲異常以外,還想在引發已捕獲異常時暫停,則勾選 Pause On Caught Exceptions 複選框。
7.函式斷點
如果想要在呼叫特定函式時暫停,可以呼叫 debug(functionName)
,其中 functionName
是要除錯的函式。 您可以將 debug()
插入您的程式碼(如 console.log()
語句),也可以從 DevTools 控制檯中進行呼叫。 debug()
相當於在第一行函式中設定程式碼行斷點。
function sum(a,b) { let result = a + b; // DevTools 會在此行暫停 return result; } debug(sum); // 傳遞函式物件,而不是字串。 sum();
如果想要除錯的函式不在範圍內,DevTools 會引發 ReferenceError
。
(function () { function hey() { console.log('hey'); } function yo() { console.log('yo'); } debug(yo); // 這行可以成功呼叫 yo(); })(); debug(hey); // 這一行不能成功呼叫 hey() 不在作用域內
如果是從 DevTools 控制檯中呼叫 debug()
,則很難確保目標函式在範圍內。所以一般還不如直接使用程式碼行斷點!
到此這篇關於在Chrome DevTools中除錯JavaScript的實現的文章就介紹到這了,更多相關Chrome DevTools除錯JavaScript內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!