原文:Debugging Javascript Like a Projavascript
當您的代碼沒有按照預期執行的時候,您是否還在用 console.log
來進行調試?若是是,那這篇文章就是爲您準備的。前端
我寫這篇文章的目的是讓您瞭解 Chrome 開發工具提供的高效工具,讓您能夠更好、更快地調試 Javascript 代碼。java
本文主要講述如下幾點內容:node
當代碼出現 bug 或沒有按照預期執行時,咱們一般會查看開發者工具中的 Sources
選項卡,接下來咱們將經過不一樣場景來深刻了解這個功能模塊。web
在閱讀本文以前,您可能習慣於使用控制檯打印某個值來調試代碼。但我但願向您介紹一種更高效的方法,一種能更深刻代碼中的方法:斷點。chrome
設置斷點一般是調試過程的第一步。雖然目前大多數瀏覽器中的內置開發工具,都容許您調試正在瀏覽的頁面,中止在特定代碼行上或者在特定語句上執行代碼,但在本文中,咱們將主要講解 Chrome 開發者工具。數組
一般,您可能但願中止執行代碼,以便您能夠逐行地查看特定的上下文。瀏覽器
一旦代碼在斷點處中止,咱們就能夠經過訪問做用域,查看調用堆棧,甚至在運行時更改代碼來進行調試。markdown
因爲使用哪一種前端技術對調試來講並不重要,爲了更方便地向您解釋斷點,我將調試用於培訓的一個 Angular 項目。異步
Sources
選項卡小提示:在 Mac 上,使用快捷鍵 ⌘ + O
能夠打開文件選擇器,您能夠在其中找到您須要調試的文件。在 Windows 上,可使用 CTRL + O
如上圖所示,咱們能夠在一行代碼上更深刻地設置斷點,例如在一行代碼裏的不一樣語句。
咱們設置了3個斷點:
priceReceived
函數執行以前中止priceReceived
被調用後當即中止,所以咱們也能夠檢查箭頭函數的返回值當調用箭頭函數時,執行中止,右側面板 Scope
將顯示當前的上下文,並容許咱們訪問全部咱們想查看的值。
以下圖所示,咱們能夠看到變量 price
的值 。
在下圖中,一旦 priceReceived
執行,第三個斷點就會被使用。
在右側面板中您可使用 Return value
查看匿名函數的返回值。
場景:您在代碼中設置了一堆斷點。
在調試時,屢次刷新頁面是很常見的操做。
您當前正在調試的代碼可能有各類斷點,有時候甚至會達到幾百個。這幾百個斷點可能會浪費您大量的時間。
在這種狀況下,能夠暫時暫停全部斷點的執行,您能夠經過切換下圖中的圖標來操做:
場景:您的代碼執行產生了錯誤,但您不想設置斷點,由於您不知道什麼時候會拋出錯誤。
在您的代碼中拋出錯誤,這樣就能夠查看代碼出現了什麼問題。
顧名思義,條件斷點就是僅在條件爲真時觸發的斷點。
例如,在上面的示例中,用戶能夠在文本區域中輸入非數值。因爲 JS 的兼容性只會顯示 NaN 而不是拋出錯誤。
場景:您的代碼比上面的代碼更復雜,而且沒法肯定什麼時候出現 NaN 。
固然,您能夠設置一個斷點,但復現錯誤並不容易,可能最終花費半小時來執行代碼。在這種狀況下,您可使用條件斷點,並僅在出現 NaN 時中止執行代碼。
以下圖:
爲了充分利用 Dev Tools,值得花一點時間學習開發工具如何幫助咱們快速單步執行代碼,而無需在每一行設置斷點。
使用 Dev Tools 中的 navigator 能夠順序逐行執行代碼。
我將在下面介紹 Step over next function call
與 Step
的不一樣。在調試異步代碼時,點擊 Step
按鈕將按時間順序移動到下一行。
Step over next function call
按鈕也會順序執行代碼,但不會進入函數調用。也就是說,函數調用將被跳過,除非您在函數中設置了斷點,不然調試器將不會在該函數中中止。
若是您仔細觀察上圖,會發現 multiplyBy 和 renderToDOM 這兩個方法執行時沒有像 Step
那樣進入函數內部。
自 Chrome 68 以來,Step Into Next function call
按鈕的做用發生了改變。它相似於上面提到的 Step
。不一樣之處在於,當進入異步代碼時,它將中止在異步代碼中,而不是按時間順序運行的代碼
如上圖所示:若是按時間順序,第32行應該已經運行,但事實並不是如此。調試器在等待2秒後才移動到第29行
假設調試代碼時,您不想進入某個函數的內部,Step Out of function call
容許您退出函數並在函數調用後的下一行中止。
上圖中發生了什麼?
renderToDOM
renderToDOM
函數的剩餘部分有時,在全局範圍內存儲某些值(例如組件類,大型數組或複雜對象)會很是有用。
例如,當您想要傳入不一樣的參數調到某個組件的方法時,在調試過程當中將這些參數添加到全局範圍能夠節省大量時間。
在上圖中,我將數組 [previous, current]
存爲全局變量。開發者工具會自動分配一個名爲 temp{n}
的變量,n 基於先前保存的變量的數目。
如上圖所示,變量被命名temp2,您能夠在控制檯中使用它,由於它如今已經是一個全局變量了!
即時輸出是 Chrome 68 中發佈的一項功能,開發工具容許您在輸入代碼時在控制檯中顯示執行的結果。
若是您仔細觀察上圖會發現,當我將保存的變量映射到字符串數組時,我沒有按下 Enter 鍵,但結果當即顯示在下一行。
查看調用堆棧是開發者工具提供的最有用的工具之一:您不只能夠在調用它們的函數中來回跳轉,還能夠在每一個步驟檢查它們的做用域。
假設咱們有一個簡單頁面和一個輸入數字的腳本,並在頁面上呈現數字乘以10.咱們將調用兩個函數:一個用來作乘法,一個用來將結果渲染到頁面中。
如上圖所示,只需單擊 「Call Stack」 窗格中的函數名稱,咱們就能夠瀏覽它們的做用域。
若是您仔細觀察會發現,每次咱們從一個函數調用跳到另外一個函數調用時,做用域都會保留,咱們能夠在這裏對每一步進行分析!
Blackboxing 腳本將經過從堆棧中排除特定的腳本或某些匹配模式的腳原本過濾調用堆棧。
例如,若是我有99%的時間只調試 userland 中的代碼感興趣,我能夠在 Blackbox 中添加一個模式,將 node_modules 文件夾下的全部腳本過濾掉。
要經過 Blackbox 過濾一個腳本,有兩種方法:
Sources
選項卡中的 JS 腳本,而後單擊「Blackbox Script」Add Pattern...
並輸入您想要加入 Blackbox 的正則,在您想要過濾大量腳本時頗有用。經過監視表達式,您能夠定義一些 Javascript 語句,在開發者工具運行顯示這些語句的結果。這是一個特別有趣的工具,由於您能夠寫任何您想要的虛擬狀況,只要它是一個有效的Javascript表達式。
例如,您能夠編寫一個結果始終爲 true 的表達式,當表達式結果爲 false 時 ,您就能夠發現當前的運行狀態存在問題。
有一個須要注意問題:
瀏覽器開發者工具是調試複雜代碼的利器。有時您可能須要比 console.log
更進一步的操做,上面提到的功能將提供深刻代碼底層的調試體驗。這些工具須要一些練習才能徹底掌握,因此若是您對部分功能還不熟悉,請不要放棄,繼續堅持使用它們。
如下是一些資料,能夠幫助您徹底掌握開發工具提供的全部功能:
歡迎轉載,記得註明做者和來源哦~~