JavaScript 除錯建議和技巧

hysic發表於2015-10-22

繼上一篇關於除錯web應用的原則的帖子後這次我們來研究一下實踐中的JavaScript除錯。

瀏覽器開發者工具

我個人最喜歡Chrome開發者工具。雖然Safari和Firefox無法達到Chrome那麼高的標準,但它們也在逐漸改善。在Firefox中,可以將Firebug和Firefox開發者工具組合使用。如果Firefox小組在改進內建開發者工具方面繼續表現優異的話,Firebug有一天可能會被淘汰。

先把個人偏好放在一邊,你應該能夠在目標瀏覽器中對任意程式碼進行試驗和除錯。你的目標瀏覽器可能包括著名的IE8,也可能不包括。

要熟悉你自己選擇的開發者工具。你還可以從IDE(整合開發環境)或者第三方軟體獲得額外的除錯支援。

在各種除錯工具中,除錯的基礎知識是相通的。事實上,我是在90年代從Borland的C開發者環境中學習的除錯基礎。斷點、條件斷點、監視與最新版Chrome開發者工具是完全相同的。2000年左右,我在Java中捕獲到第一例異常。堆疊跟蹤(Stack traces)的概念依然適用,即使JavaScript術語將其稱作錯誤(Error),檢查堆疊跟蹤仍然和以前一樣有用。

有些知識點是前端開發特有的。例如:

  • DOM檢查
  • DOM斷點
  • 除錯事件
  • 記憶體洩露分析

斷點

使用debugger語句可以在原始碼中增加斷點。一旦到達debugger語句,執行中斷。當前作用域的上下文出現在控制檯中,還有所有的區域性變數和全域性變數。將滑鼠游標移到變數上可以檢視變數的值。

在程式碼中還可以建立條件斷點:

還可以根據自己需要在開發者工具中插入斷點和條件斷點。在Chrome開發者工具中,在Sources檢視中點選行號即可增加斷點。如果在斷點上點選右鍵並選擇“編輯斷點(Edit Breakpoint)”,你還可以增加斷點條件。

節點變化的斷點

如果你的任務是除錯垃圾程式碼,你可能會有這樣的問題:為什麼DOM節點在執行過程中發生了改變。Chrome開發者工具提供了一種方便的斷點,可用來檢測元素樹中的節點變化。

在Elements檢視中,右鍵點選一個元素,從右鍵選單中選擇“Break on…”。

節點變化的斷點

DOM斷點的型別可能包括:

  • 選定節點樹狀子目錄(sub-tree)中的節點變化,
  • 選定節點的屬性發生變化,
  • 節點被刪除。

避免記錄引用型別

當記錄物件或陣列時,原始型別的值在引用物件記錄中可能會發生變化。當檢視引用型別時一定要記住,在記錄和檢視期間,程式碼執行可能會影響觀測到的結果

例如,在Chrome開發者工具中執行以下程式碼:

記錄的第二個和第三個屬性的值是正確的,第一個屬性中物件引用的值是不可靠的。當你第一次在開發者工具中顯示這個屬性時,amount域的值就已經確定了。無論你對同一個引用關閉並重新開啟多少次,這個值都不會變化。

記錄參考型別

永遠記得你在記錄什麼。記錄原始型別時,使用帶斷點的watch表示式。如果是非同步程式碼,避免記錄引用型別

表格記錄

在一些開發者工具中,你可以用console.table在控制檯中記錄物件陣列。

嘗試在你的Chrome開發者工具中執行下列程式碼:

輸出是非常好看的表格。所有原始型別都立刻顯示出來,它們的值反應記錄時的狀態。也可以記錄複雜型別,顯示內容為其型別,內容無法顯示。因此,console.table只能用來顯示具有原始型別值的物件構成的二維資料結構。

XHR斷點

有時你可能會遇到錯誤的AJAX請求。如果你無法立刻確認提交請求的程式碼,XHR斷點可以幫你節省時間。當提交某一特殊型別的AJAX時,XHR斷點將會終止程式碼的執行,並將提交請求的程式碼段呈現給使用者。

在Chrome開發者工具的Sources標籤頁中,其中一個斷點型別就是XHR斷點。點選+圖示,你可以輸入URL片段,當AJAX請求的URL中出現這個URL片段時,JavaScript程式碼將會中斷。

事件監聽器斷點

Chrome開發者工具可以捕獲所有型別的事件,當使用者按下一個鍵、點選一下滑鼠時,可以對觸發的事件進行除錯。

異常時暫停

Chrome開發者工具可以在丟擲異常時暫停執行JavaScript程式碼。這可以讓你在Error物件被建立時觀察應用的狀態。

異常時暫停

程式碼片段

Sources標籤頁左側皮膚上有一個程式碼片段(Snippet)子標籤頁,可用於儲存程式碼片段,幫你除錯程式碼。

如果你堅持使用控制檯除錯,反覆寫相同的程式碼,你應該將你的程式碼抽象成除錯片段。這樣的話,甚至還可以把你的除錯技巧教給你的同事。

Paul Irish釋出過一些基本的除錯程式碼片段,例如在函式執行前插入斷點。審查這些程式碼片段,並在網上搜尋其他程式碼片段,這是很有價值的

在函式執行前插入斷點

如果你可以得到函式呼叫的原始碼,你還可以在函式呼叫前插入斷點來終止函式的執行。如果你想除錯f函式,用debug(f)語句可以增加這種斷點。

Unminify最小化程式碼

譯者注:unminify 解壓縮並進行反混淆

儘可能使用 source map。有時生產程式碼不能使用source map,但不管怎樣,你都 不應該直接對生產程式碼進行除錯

(譯者注:sourcemap 是針對壓縮合並後的web程式碼進行除錯的工具)

如果沒有source map的話,你最後還可以求助於Chrome開發者工具Sources標籤頁中的格式化按鈕(Pretty Print Button)。格式化按鈕{}位於原始碼文字區域的下方。格式化按鈕對原始碼進行美化並改變行號,這使得除錯程式碼更加方便,堆疊跟蹤更加有效。

格式化按鈕只有在不得已時才會使用。從某種意義上來說,醜程式碼就是難看,因為程式碼中的命名沒有明確的語義

DOM元素的控制檯書籤

Chrome開發者工具和Firebug都提供了書籤功能,用於顯示你在元素標籤頁(Chrome)或HTML標籤頁(Firebug)中最後點選的DOM元素。如果你依次選擇了A元素、B元素和C元素,

  • $0 表示C元素
  • $1 表示B元素
  • $2 表示A元素

如果你又選擇了元素D,那麼$0$1$2$3分別代表DCBA

訪問呼叫棧

Chrome開發者工具中的Sources標籤頁也在Watch表示式下面顯示呼叫棧。

效能審查

效能審查工具通常是很有用的。這些工具可以用於防止記憶體洩露,還可以檢測到你的網站哪裡需要優化。由於這些工具並不瞭解你的產品,你可以忽略其某些建議。通常來說,效能分析工具能夠有效範圍,可以使你的網站顯著優化。

審查工具舉例:

  • Chrome開發者工具的Audit標籤頁
  • YSlow

熟能生巧

你可能熟悉某些除錯技巧,其他技巧也會幫你節省不少時間。如果你開始在實踐中使用這些技巧,我建議你幾周之後重新閱讀本文。你將會驚奇地發現,你的關注點在幾周內就發生了變化。

相關文章