工欲善其事,必先利其器。最近在寫代碼的時候愈加以爲不是代碼有多難,而是當代碼出了問題該如何調試,如何追溯本源,這纔是最難的。javascript
響應這個要求,我決定寫一個關於調試實戰系列。原本不打算寫這個基礎篇章,爲了整個的完整性。(不喜勿噴)html
注意,如下yifenghua.win域名下線,替換爲https://hua1995116.github.io/myblog/vue
打算出三個篇章java
1.急速 debug 實戰一 (瀏覽器 - 基礎篇)webpack
3.急速 debug 實戰三 (Node - webpack插件,babel插件,vue源碼篇)github
因此示例在如下環境經過。web
操做系統: MacOS 10.13.4chrome
Chrome: 版本 72.0.3626.81(正式版本) (64 位)瀏覽器
可能不少人如今還比較頻繁的用着 console.log
的方式調試着代碼,這種方式不說他絕對的很差,只是相比之下斷點有如下兩個優點:
使用 console.log()
,您須要手動打開源代碼,查找相關代碼,插入 console.log()
語句,而後從新加載此頁面,才能在控制檯中看到這些消息。 使用斷點,無需瞭解代碼結構便可暫停相關代碼。
在 console.log()
語句中,您須要明確指定要檢查的每一個值。 使用斷點,DevTools 會在暫停時及時顯示全部變量值。 有時在您不知道的狀況下,有些變量會影響您的代碼。
1.打開: hua1995116.github.io/myblog/exam…
2.在 Number 1
文本框中輸入 5。
3.在 Number 2
文本框中輸入 1。
4.點擊 Add Number 1 and Number 2
。 按鈕下方的標籤顯示5 + 1 = 51
。 結果應爲 6。 這就是咱們須要修正的問題。
第 1 步:重現錯誤
1.經過按Command+Option+I (Mac)
或 Control+Shift+I(Windows、Linux)
,打開 DevTools。 此快捷方式可打開 Console
面板。
2.點擊 Sources 標籤。
第 3 步:使用斷點暫停代碼
若是退一步思考應用的運做方式,您能夠根據經驗推測出,使用與 Add Number 1 and Number 2 按鈕關聯的 click 事件偵聽器時計算的和不正確 (5 + 1 = 51)
。 所以,您可能須要在 click
偵聽器運行時暫停代碼。 Event Listener Breakpoints 可以讓您完成此任務:
function onClick() { 複製代碼
若是是在其餘代碼行暫停,請按 Resume Script Execution 繼續執行腳本, 直到在正確的代碼行暫停爲止。
一個常見的錯誤緣由是腳本執行順序有誤。 能夠經過單步調試代碼一次一行地檢查代碼執行狀況,準確找到執行順序異常之處。 當即嘗試:
在 DevTools 的 Sources 面板上,點擊 Step into next function call 單步執行時進入下一個函數調用,以便一次一行地單步調試 onClick() 函數的執行。 DevTools 突出顯示下面這行代碼:
if (inputsAreEmpty()) { 複製代碼
點擊 Step over next function call 單步執行時越過下一個函數調用。 DevTools 執行但不進入 inputsAreEmpty()
。 請注意 DevTools 是如何跳過幾行代碼的。 這是由於 inputsAreEmpty()
求值結果爲 false,因此 if
語句的代碼塊未執行。
這就是單步調試代碼的基本思路。 若是看一下 get-started.js
中的代碼,您會發現錯誤多半出在 updateLabel()
函數的某處。 您可使用另外一種斷點來暫停較接近很可能出錯位置的代碼,而不是單步調試每一行代碼。
代碼行斷點是最多見的斷點類型。 若是您想在執行到某一行代碼時暫停,請使用代碼行斷點:
看一下 updateLabel()
中的最後一行代碼:
label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum; 複製代碼
在這行代碼的左側,您能夠看到這行代碼的行號是 32。 點擊 32。 DevTools 會在 32 上方放置一個藍色圖標。 這意味着這行代碼上有一個代碼行斷點。 DevTools 如今始終會在執行此行代碼以前暫停。
點擊 Resume script execution 繼續執行腳本 。 腳本將繼續執行,直到第 32 行。 在第 29 行、第 30 行和第 31 行上,DevTools 會在各行分號右側輸出 addend1
、addend2
和 sum
的值。
addend1
、addend2
和 sum
的值疑似有問題。 這些值位於引號中,這意味着它們是字符串。 這個假設有助於說明錯誤的緣由。 如今能夠收集更多信息。 DevTools 可提供許多用於檢查變量值的工具。
方法 1:Scope 窗格 在某代碼行暫停時,Scope 窗格會顯示當前定義的局部和全局變量,以及各變量值。 其中還會顯示閉包變量(若是適用)。 雙擊變量值可進行編輯。 若是不在任何代碼行暫停,則 Scope 窗格爲空。
方法 2:監視表達式 Watch Expressions 標籤可以讓您監視變量值隨時間變化的狀況。 顧名思義,監視表達式不只限於監視變量。 您能夠將任何有效的 JavaScript 表達式存儲在監視表達式中。 當即嘗試:
點擊 Watch 標籤。 點擊 Add Expression 添加表達式。 輸入 typeof sum
。 按 Enter
鍵。 DevTools 會顯示 typeof sum: "string"
。 冒號右側的值就是監視表達式的結果。
正如猜測,sum 的求值結果本應是數字,而實際結果倒是字符串。 如今已肯定這就是錯誤的緣由。
方法 3:控制檯 除了查看 console.log()
消息之外,您還可使用控制檯對任意 JavaScript 語句求值。 對於調試,您可使用控制檯測試錯誤的潛在解決方法。 當即嘗試:
若是您還沒有打開 Console 抽屜式導航欄,請按 Escape 將其打開。 該導航欄將在 DevTools 窗口底部打開。 在 Console 中,輸入 parseInt(addend1) + parseInt(addend2)
。 此語句有效,由於您會在特定代碼行暫停,其中 addend1
和 addend2
在範圍內。 按 Enter
鍵。 DevTools 對語句求值並打印輸出 6
,即您預計演示頁面會產生的結果。
您已找到修正錯誤的方法。 接下來就是嘗試經過編輯代碼並從新運行演示來使用修正方法。 您沒必要離開 DevTools 就能應用修正。 您能夠直接在 DevTools UI 內編輯 JavaScript 代碼。 當即嘗試:
var sum = addend1 + addend2
替換爲 var sum = parseInt(addend1) + parseInt(addend2)
。 3.按 Command+S (Mac)
或 Control+S(Windows、Linux)
以保存更改。斷點類型 | 狀況 |
---|---|
代碼行 | 在確切的代碼區域中。 |
條件代碼行 | 在確切的代碼區域中,且僅當其餘一些條件成立時。 |
DOM | 在更改或移除特定 DOM 節點或其子級的代碼中。 |
XHR | 當 XHR 網址包含字符串模式時。 |
事件偵聽器 | 在觸發 click 等事件後運行的代碼中。 |
異常 | 在引起已捕獲或未捕獲異常的代碼行中。 |
函數 | 任什麼時候候調用特定函數時。 |
在知道須要調查的確切代碼區域時,可使用代碼行斷點。 DevTools 始終會在執行此代碼行以前暫停。
在 DevTools 中設置代碼行斷點:
在代碼中調用 debugger
可在該行暫停。 此操做至關於使用代碼行斷點,只是此斷點是在代碼中設置,而不是在 DevTools 界面中設置。
console.log('a');
console.log('b');
debugger;
console.log('c');
複製代碼
若是知道須要調查的確切代碼區域,但只想在其餘一些條件成立時進行暫停,則可以使用條件代碼行斷點。
若要設置條件代碼行斷點:
使用 Breakpoints 窗格能夠從單個位置停用或移除代碼行斷點。
顯示兩個代碼行斷點的 Breakpoints 窗格:一個代碼行斷點位於 get-started.js
第 15 行,另外一個位於 第 32 行
若是想要暫停更改 DOM 節點或其子級的代碼,可使用 DOM 更改斷點。
若要設置 DOM 更改斷點:
Subtree modifications: 在移除或添加當前所選節點的子級,或更改子級內容時觸發這類斷點。 在子級節點屬性發生變化或對當前所選節點進行任何更改時不會觸發這類斷點。
Attributes modifications:在當前所選節點上添加或移除屬性,或屬性值發生變化時觸發這類斷點。
Node Removal:在移除當前選定的節點時會觸發。
若是想在 XHR 的請求網址包含指定字符串時中斷,可使用 XHR 斷點。 DevTools 會在 XHR 調用 send()
的代碼行暫停。
注:此功能還可用於 Fetch 請求。
例如,在您發現您的頁面請求的是錯誤網址,而且您想要快速找到致使錯誤請求的 AJAX 或 Fetch 源代碼時,這類斷點頗有用。
若要設置 XHR 斷點:
若是想要暫停觸發事件後運行的事件偵聽器代碼,可使用事件偵聽器斷點。 您能夠選擇 click
等特定事件或全部鼠標事件等事件類別。
若是想要在引起已捕獲或未捕獲異常的代碼行暫停,可使用異常斷點。
若是想要在調用特定函數時暫停,能夠調用 debug(functionName)
,其中 functionName
是要調試的函數。 您能夠將 debug()
插入您的代碼(如 console.log()
語句),也能夠從 DevTools 控制檯中進行調用。 debug()
至關於在第一行函數中設置代碼行斷點。
function sum(a, b) {
let result = a + b; // DevTools pauses on this line.
return result;
}
debug(sum); // Pass the function object, not a string.
sum();
複製代碼
若是想要調試的函數不在範圍內,DevTools 會引起 ReferenceError
。
(function () {
function hey() {
console.log('hey');
}
function yo() {
console.log('yo');
}
debug(yo); // This works.
yo();
})();
debug(hey); // This doesn't work. hey() is out of scope.
複製代碼
若是是從 DevTools 控制檯中調用 debug()
,則很難確保目標函數在範圍內。 下面介紹一個策略:
debug()
。咱們在調試一些 hover 屬性的時候,每每想要調整 hover 後顯示的元素,可是每當咱們移到觀察此元素的時候就會消失。這使得調試很是不方便。下面就提供幾種場景,分別來給出調試的方案。
demo: hua1995116.github.io/myblog/exam…
單純的 hover 屬性咱們只須要找到觸發的元素。在這裏是咱們 button。因此咱們在 elements 中找到咱們對應的 hover 元素。右鍵-> force state -> :hover
若是是經過 mouse (鼠標事件來觸發的)而且觸發元素是寫在觸發元素內的狀況。能夠經過在當前觸發元素。右鍵 -> Break on -> subtree modifications。 而後再次觸發,選擇跳過斷點。就可使得元素出現。
若是是經過 mouse (鼠標事件來觸發的)而且觸發元素是寫在觸發元素外的狀況。能夠經過斷點觸發來阻斷。(此方法也兼容 mouser inner 的狀況)。當觸發元素的時候按下 F8 (Windwos)
/ command + \ (Mac)
developers.google.com/web/tools/c…
友情連接: huayifeng.top/