寫在前面:文章是 Chrome DevTools 介紹系列的一部分,查看所有文章能夠關注 Github 上的 Chrome DevTools 詳解,也能夠關注這個系列所在的項目:front-end-study。git
在 Chrome 中調試 JS 代碼,那你不得不與 Chrome DevTools 的 Sources 面板打交道,因此文章主要經過介紹 Sources 面板上的各部分功能來介紹如何調試網頁中的 JS。github
先來認識一下 Sources 面板(以個人 Github 首頁舉例)。ajax
能夠看到面板被分爲左中右三個部分,左邊是文件導航,中間是文件的具體內容,右邊能夠統稱爲調試面板。整個面板就像一個 IDE,因此仍是挺親切的。瀏覽器
左邊的文件導航面板包含 3 個面板:,分別是:框架
Sources:這個面板很好理解,展現了網頁所用到的全部文件函數
Content scripts:Content scripts 指的是 Chrome 拓展注入在網頁中的腳本。好比我安裝了一個叫 JSONView 的 Chrome 拓展,打開個人 Content scripts 面板會看到:測試
Snippets:Snippets 的含義是片斷,在這裏指的是一小段程序,這個一小段程序跟在其餘地方不同的是,能夠訪問這個頁面中的變量和函數等。spa
中間面板的其餘操做都比較顯而易見,只是有 4 點須要簡單提一下。debug
標記 一、2 處能夠隱藏/展開左右兩個面板,標記 3 處格式化代碼,使得代碼變得易於閱讀,當代碼被壓縮時尤爲有用。另外須要提一下的是打開文件的快捷方式,能夠用 Cmd + p / Ctrl + p 在任何一個功能面板上搜索一個文件,按 enter 鍵在 Sources 面板上打開。3d
右邊的調試面板比較複雜,須要藉助調試的例子來解釋做用。不過咱們能夠先大概熟悉一下:
右側的面板爲上下結構,上面是一組功能按鈕,下面由不少面板組成,這些面板中,看名字大概能知道第二個顯示的是調用棧,從四個開始就是各類類型的斷點。那真相是什麼呢?咱們下面結合調試實例來解釋這些按鈕/面板的功能。
本文用到的測試代碼爲本身所寫的 Demo。
打開一個文件,中間的面板中顯示了代碼,代碼的左側有代碼行號,代碼行號所在的位置叫作行號槽,點擊行號槽,爲相應的行添加斷點,並在相應的行號上面加上一個相似肩章的五邊形圖標。特別提一下的是,這個圖標的顏色是藍色的。以下:
另外,若是一條語句由多行組成,若是在這條語句的行中添加斷點的話,那麼斷點將會被加到下一條語句。舉例以下:
在上面的代碼中,你能夠在 13 行添加斷點,但若是你想在 14-17 行添加斷點的話,那麼斷點將會被添加到 19 行。另外,你也不能爲空行添加斷點,那也會被添加到下一條語句上。好比你想在 18 行添加斷點,但實際會被添加到 19 行。
條件斷點
右鍵一個沒有添加斷點的行號,選擇 "Add conditional breakpoint",輸入你的條件,當條件知足時,斷點纔會生效。回車後,效果以下:
能夠看見,條件斷點跟通常斷點的區別就是顏色變成了黃色。
行內斷點
以前有人在評論裏問,爲何個人這個系列文章要加一個 v57 這個前提,行內斷點就是一個很好的回答。行內斷點是從 Chrome(v55) 纔有的一個功能,意思是你能夠在一行內添加多個斷點。看下面的例子:
跟前面添加斷點方式同樣,我先在 15 行添加了一個斷點,當程序中斷在 15 行時,出現了上圖的例子。但與通常的例子不一樣的是,上面有 3 處標紅的位置,表示 3 處斷點。但第 1 個斷點跟後 2 個不同的是,第 1 個斷點是默認處於激活狀態,然後 2 個則不是,只有點擊激活後才能生效。
忽略:若是你想暫時忽略某個斷點,右鍵斷點,選擇 "Disable breakpoint"
修改:修改斷點生效的條件。你能夠將一個非條件斷點經過這個方式修改爲條件斷點,也能夠將條件斷點變成非條件斷點
刪除:你能夠直接點擊斷點,或者右鍵 "Remove breakpoint"
右鍵行號槽的時候,第一個選項老是:"Blackbox Script"。
那什麼是黑盒腳本呢?
咱們寫項目時,不少時候是要引用第三方庫或框架的,當咱們調試時,調試的對象應該是咱們本身寫的代碼,但不少時候,咱們常常在焦灼地進行下一步下一步時,忽然代碼跳到了第三方庫或框架的源碼上去,這讓咱們焦灼的心裏更添了一把柴火。黑盒腳本就是用來解決這個問題的。它可以將一個腳本文件標記爲 "Blackbox Script",那麼咱們就永遠不可能進入這個文件內部,這個文件對咱們來說就是一個黑盒子。爲何要強調「永遠」呢?由於不只普通的斷點不能訪問這個被標記了的腳本,其餘的,好比說 DOM 斷點、事件斷點等等都沒法訪問那個腳本文件內部。
這個面板會顯示你全部的經過行號留下的斷點。你能夠右鍵管理某個或所有斷點:
Remove Breakpoints:刪除選中的斷點
Deactivate Breakpoints:暫時忽略全部斷點
Disable all Breakpoints:功能同上(與上一功能有細微差異,但表現相似)
Remove all Breakpoints:刪除全部斷點
除了普通的中斷類型,咱們下面再介紹幾款其餘類型的。
在 Elements 面板,右鍵 body 元素,插入 "attribute modifications breakpoint",在 Sources 面板中顯示以下:
查看 DOM 斷點的詳細信息請查看另外一篇博客:Elements
XHR 斷點跟 DOM 斷點很相似,經過 XHR 斷點能夠很容易的找到 ajax 調用的觸發點和調用堆棧。最新的 Chrome DevTools 中要麼爲全部 ajax 調用添加斷點,要麼都不添加斷點。
展開 Event Listener Breakpoints 能夠看到一組事件類型,展開一個事件類型能夠看到具體的事件名稱。
每一個事件名稱和事件類型前面都有個複選框,選中即指當頁面中觸發了所選的事件的話,就會觸發中斷。
顯示全局監聽器,在瀏覽器中 window 是全局對象,因此在 Global Listeners 面板中顯示綁定在 window 對象上的事件監聽。
這個跟上面幾種不同,這個是放在功能按鈕組裏面的。
選中 "Pause on exceptions" 按鈕,如上圖,當執行的腳本出現異常時會觸發中斷。
介紹瞭如何添加斷點的方式以及幾款中斷類型,下面介紹一下如何利用斷點進行調試。
咱們先來介紹幾個功能按鈕:
:當程序中斷在斷點處時,點擊去往下一個斷點
:當程序中斷在斷點處時,長按上面的按鈕出現,點擊這個按鈕能夠在 0.5s 內忽略任何中斷,當中斷出如今循環內部時通常比較有用
:執行下一條語句
:當中斷停留在一個函數調用處時,點擊這個按鈕會進入函數內部,而上面的按鈕則會執行函數調用的下一句,不會進入函數內部
:當中斷停留在函數內部時,點擊這個按鈕則會跳出函數內部,停留在函數調用的下一個語句
:在不取消斷點標記的狀況下,使得全部斷點失效
Scope 面板顯示了你當前定義的全部屬性的值,例子如上圖。除了 Scope 面板,你還能夠在左側的代碼區域,中斷的旁邊看到語句中包含的變量的值。除此之外,你還能夠把鼠標放在變量上面,也顯示對應變量的值。
Scope 會顯示三種類型的值: Local、Closure 和 Global。
當代碼中斷在一處時,Call Stack 面板會顯示代碼的執行路徑。好比在 a() 中調用了 b(),b() 中調用了 c(),那麼中斷若是在 c() 內部的話,那麼 Call Stack 面板會依次顯示 c、b、a。
在 JS 中,咱們經常會寫匿名函數,顯而易見,在調試時,尤爲在查看調用棧時,這樣很不友好,因此建議儘可能爲每一個函數命名。
若是還記得前面所講的黑盒腳本(Blackbox Script)的話,這裏就再重複一句,是的,黑盒腳本永遠不可見,因此你即便在查看調用棧時你也無法看到黑盒腳本里的內容。這種狀況下會出現下面這樣的結果:
前面講 Scope 面板時介紹了三種查看中斷狀態下的變量值,還有一個隱蔽的小技巧也能查看,按 esc 按鍵打開 Console drawer(不清楚是什麼能夠看Console),而後在裏面輸入你想查看的值,回車,bingo~
若是你覺得 Chrome DevTools 就簡單看看這些值那就過小瞧她了,在中斷狀態下,還能動態修改變量的值。好比中斷處有個變量叫 v,值是 1,若是我直接按 "Resume script execution" 的話,那麼下一次的 v 也是 1,但若是我在按恢復執行按鈕以前,我在 Console drawer 中輸入 v = 2
回車,那麼,下一處的 v 就是 2 了。
還有更厲害的,你不只能夠修改變量的值,你還能夠修改代碼!當程序中斷時,你能夠在 Sources 面板修改你的代碼。
介紹到這,還有一個面板:Watch,下面就講講這個。
正如名字所表示的,觀察,觀察什麼呢?主要觀察變量。
前面咱們講過,當程序中斷時,能夠查看這個狀態下的變量的值,但侷限是隻能一個一個查看,而 Watch 的好處是可讓咱們同時查看多個變量。你能夠經過 "+" 來添加變量,當添加的變量存在時會顯示對應的值,不存在的話則會顯示 "not availble"。須要注意的是,這裏的變量不會隨着代碼的執行而發生改變,因此到了下一個狀態時,你須要點擊刷新按鈕來得到關注的變量的新的值。
如今的項目幾乎都是通過編譯過的,因此當咱們調試時會與編譯後的代碼打交道,但那並非咱們想要的。不要急,Chrome DevTools 提供了預處理過的代碼與源碼的映射,主要表如今兩點:
在 console 上,源連接指向的是源碼,而不是編譯後的文件
在 debug 時,在 Call Stack 面板上的源連接指向的也是源碼,不是編譯後的文件
不過須要注意的是,上面所講的能查看源碼的前提是 Chrome DevTools 在設置中提供了相應權限,具體是:Settings - Sources - Enable Javascript source maps / Enable CSS source maps,勾選這兩項便可。不過,默認狀況下就是勾選。