1. 程式人生 > >14招搞定JavaScript調試

14招搞定JavaScript調試

network 條件 ajax請求 vol car 開發 問題 框架 copyright

14招搞定JavaScript調試

譯者按: 很多時候,大家可能只是依靠console.log來調試JavaScript代碼,這樣做的局限性不言而喻,這篇博客將教你幾招實用的調試技巧。

  • 原文: The 14 JavaScript debugging tips you probably didn’t know)
  • 譯者: Fundebug

為了保證可讀性,本文采用意譯而非直譯。另外,本文版權歸原作者所有,翻譯僅用於學習。

掌握工具的使用方法可以極大提高解決問題的效率。盡管JavaScript以難以Debug著稱,如果你知道一些技巧可以讓你更快地搞定它。本文我總結了14個Debug小技巧,也許會對你有用!

大多數技巧都是針對Chrome檢查器(Inspector)和Firefox,盡管有很多人使用其他檢查器。

1. debugger;

除了console.log之外,debugger;是我最喜歡的快速debug的工具。一旦在代碼中加入了這行語句,Chrome在執行的時候會自動在該行停下來。你甚至可以和條件語句配合使用,僅僅在你需要它的時候開啟。

if(thisThing){ debugger; }

2. 將對象以表格的形式展示

有時候,你需要查看一個復雜的對象元素。通常,我們都會使用console.log將其打印出來然後查看。其實,你還可以使用console.table,讓對象更加美觀地呈現出來。

var animals = [ { animal: ‘Horse‘, name: ‘Henry‘, age: 43 }, { animal: ‘Dog‘, name: ‘Fred‘, age: 13 }, { animal: ‘Cat‘, name: ‘Frodo‘, age: 18 } ]; console.table(animals);

輸出樣式:


技術分享

3. 嘗試適配各種機型屏幕大小

如果你擁有各種型號的手機那麽測試會相對簡單,但是現實可不會這樣。其實,你可以直接在瀏覽器你們改變viewport的大小來查看效果。谷歌瀏覽器提供了非常強大的功能。在谷歌開發者面板,點擊toogle device mode

按鈕,就可以選擇不同的設備大小了。


技術分享

4. 如何快速找到對應的DOM元素

構造一個DOM元素,然後在控制臺(Console)下面使用。谷歌瀏覽器調試器(Chrome Inspector)保留了最後5個DOM元素的歷史。最後一個標記為$0,倒數第二個$1, 以此類推。

如果你按照item-4item-3item-2item-1item-0的順序點擊這些元素,那麽你可以在控制臺下使用$x來訪問它們。


技術分享

5. 使用console.time()和console.timeEnd()來記錄時間

了解代碼的執行時間是非常有用的,特別是調試耗時的for循環。你可以通過定義不同的名字來設置多個timer。我們來演示一下如何操作:

console.time(‘Timer1‘); var items = []; for(var i = 0; i < 100000; i++){ items.push({index: i}); } console.timeEnd(‘Timer1‘);

技術分享

6. 獲取某個函數的Stacktrace

你也許知道不少JavaScript框架,它們可以一鍵快速生成大量代碼。代碼裏面包含各種view和事件觸發器,最終你會想要搞明白某些函數是如何被調用的。

因為JavaScript並不是一個很結構化的語言,所有有時候要搞清楚何時如何發生的還是比較困難的。在這個時候,我們可以使用console.trace來debug JavaScript。

比如,如果你想看到一個Car實例下,funcZ的整個堆棧詳情:

var car; var func1 = function() { func2(); } var func2 = function() { func4(); } var func3 = function() { } var func4 = function() { car = new Car(); car.funcX(); } var Car = function() { this.brand = ‘volvo’; this.color = ‘red’; this.funcX = function() { this.funcY(); } this.funcY = function() { this.funcZ(); } this.funcZ = function() { console.trace(‘trace car’) } } func1(); var car; var func1 = function() { func2(); } var func2 = function() { func4(); } var func3 = function() { } var func4 = function() { car = new Car(); car.funcX(); } var Car = function() { this.brand = ‘volvo’; this.color = ‘red’; this.funcX = function() { this.funcY(); } this.funcY = function() { this.funcZ(); } this.funcZ = function() { console.trace(‘trace car’) } } func1();

使用console.trace,輸出結果如下:


技術分享

我們可以清晰地看到func1調用func2func2調用func4func4創建了一個Car的實例,然後調用了car.funcX,等等。

有時候,盡管你認為對自己的代碼非常清楚,使用console.trace依然可以幫你快速定位函數。比如,你想要改進代碼,那麽通過trace可以獲取到所有相關的函數,而且每一個都可以點擊直接跳轉,就像一個快捷菜單一樣。

廣告: 如果你需要監控線上JavaScript代碼的錯誤的話,歡迎免費使用Fundebug!

7. 將minify的代碼還原

有時候,生產環境的代碼出現問題,然而source map並沒有和壓縮的代碼綁定在一起,所有無法看到還原的代碼。不用擔心,谷歌瀏覽器可以將JavaScript代碼還原到一個可讀的樣式。盡管還是比不上真實的代碼,但是可以很好的幫助你去分析問題了。點擊{}來結構化代碼:


技術分享

8. 快速定位需要Debug的函數

設想我們想要在函數中設置一個斷點,最常見的兩種方式是:

  1. 在檢查器中找到這一行代碼,然後設置斷點;
  2. 在代碼中添加debugger

無論哪種方法,你都需要在所有的代碼文件中首先找到需要debug的那一行。

還有一個不常用的方式是使用控制臺(console),使用debug(funcName),腳本會在那行函數處暫停。使用這個方法可以很快定位函數,但是對於私有和匿名函數不適用。(註意:debug和console.debug不是同一個事情!)

var func1 = function() { func2(); }; var Car = function() { this.funcX = function() { this.funcY(); } this.funcY = function() { this.funcZ(); } } var car = new Car();

在控制臺輸入debug(car.funcY),腳本會在函數調用car.funcY處進入debug模式。


技術分享

9. 屏蔽不相關腳本

我們的代碼中都會引入不少庫函數和框架。大多數都是經過測試,幾乎沒有什麽bug的。但是debugger會一不小心跳進去。因此,我們可以選擇將這些腳本屏蔽。可以查看谷歌瀏覽器屏蔽文件的設置和火狐瀏覽器屏蔽文件的設置。

10. 個性化console.log信息

在一些很復雜的Debug中,我們需要輸出很多行的日誌,使用Console.logconsole.debugconsole.warnconsole.infoconsole.error。你可以使用過濾器來查看特定的消息,但是有時候你會發現這樣並不夠。我們可以使用更加富有創造力的方法,使用CSS來個性化定義Console.log打印的消息:

console.todo = function(msg) { console.log(‘ % c % s % s % s‘, ‘color: yellow; background - color: black;’, ‘–‘, msg, ‘–‘); } console.important = function(msg) { console.log(‘ % c % s % s % s’, ‘color: brown; font - weight: bold; text - decoration: underline;’, ‘–‘, msg, ‘–‘); } console.todo(“This is something that’ s need to be fixed”); console.important(‘This is an important message’);

輸出的結果如下:


技術分享

你可以用%s來輸出字符串,%i來輸出數字,%c來自定義格式。如果你使用單頁面框架,對於視圖(view)的console消息使用一種格式,模型(model)、集合,控制器各自使用不同的格式。甚至,你可能想要更短的名字,類似於wlog, clog和mlog。

11. 查看某個函數調用和其參數值

在谷歌瀏覽器控制臺,你可以一直觀察某個函數。每次它被調用,都會打印傳入的參數值。

var func1 = function(x, y, z) { //.... };

技術分享

使用monitor函數可以獲取到函數運行時傳入的參數值。但是,有一個不足在於並沒有指明該函數的形參個數。所以func1實際上是需要三個參數的,但是只傳入了兩個。如果忽略了這種情況,那麽可能會導致bug出現。

12 在控制臺快速訪問元素

在控制臺使用查詢選擇器(querySelector)很方便, 使用$(‘css-selector‘)就可以返回第一個匹配的元素,$$(‘css-selector‘)會返回所有匹配的元素。如果你會多次使用某個元素,甚至可以將其保存到變量中。


技術分享

13 Postman很好(但是Firefox更快)

很多開發者使用Postman來發送Ajax請求。Postman非常好用,但是打開一個新的窗口,並且配置請求對象還是有點繁瑣。

如果你不需要擔心使用cookie認證,那麽你可以在Firefox中編輯和重發請求。

打開檢查器,跳轉到網絡(network)標簽。右鍵點擊選中的請求,選擇編輯和重發選項。

下圖是我將同一個GET請求的屬性編輯後再次發送出去的情況:


技術分享

14 監控節點元素變化並中斷

有時候DOM莫名其妙變化了,然而你並不知道為啥。好在谷歌瀏覽器提供了一個功能可以在DOM元素變化的時候暫停執行。在谷歌檢查器下,右鍵選中的元素,然後選定要監控的變化類型:Subtree Modifications, Attributes Modifications, Node Removal。


技術分享


您的用戶遇到BUG了嗎?

14招搞定JavaScript調試