這次帶給大家JS調試使用詳解,JS調試的注意事項有哪些,以下就是實戰案例,一起來看一下。
試想:出現了某個bug,有人用幾分鐘就搞定了,有人用了半天或一天找不到原因。你願意當前者還是後者呢?想當前者的就請好好看完本篇文章吧。文中涉及較多Gif演示動畫請注意。
前言:任何程式設計師都少不了要去調試程式碼,不管你是高手還是菜鳥,調試程式都是一項必不可少的工作。一般來說調試程式是在編寫程式碼之後或測試期修改Bug 時進行的,往往在調試程式碼期間更加能夠體現程式設計者的水平高低以及分析問題的準確度。不少初學者在尋找錯誤原因時,總是不得要領,花了大量時間卻無法解決一些最終證明是相當簡單的Bug。掌握各種調試技巧,必定能在工作上發揮事半功倍的效果。譬如,快速定位問題、降低故障機率、幫助分析邏輯錯誤等等。而在網路前端開發越來越重要的今天,如何在前端開發中降低開發成本,提升工作效率,掌握前端開發調試技巧尤其重要。
本文將一一講解各種前端JS調試技巧,也許你已經熟練掌握,那讓我們一起來溫習,也許有你沒見過的方法,不妨一起來學習,也許你尚不知如何調試,趕緊趁此機會填補空白。
1、骨灰等級調試大師Alert
那還是網路剛起步的時代,網頁前端也主要以內容展示為主,瀏覽器腳本只能為頁面提供非常簡單的輔助功能的時候。那時候,網頁主要運行在以IE6為主的瀏覽器中,JS的調試功能還非常弱,只能透過內建在Window物件中的alert方法來調試,那時看起來應該是這個樣子:
需要說明一點,這裡看到的效果,並非當年的IE瀏覽器中看到的效果,而是在高版本IE中的效果。此外,當年似乎還沒有這麼高級的控制台,而alert的使用也是在真實的頁面JS程式碼中。雖然,alert的調試方式很原始,但當時確實有它不可磨滅的價值,甚至到今天,已然有其用武之地。
2、新一代調試王者Console
隨著JS在Web前端中能做的事情越來越多,責任越來越大,而地位也越來越重要。傳統的alert調試方式已經漸漸無法滿足前端開發的種種場景。而且alert調試方式彈出的調試信息,那個窗口著實不太美觀,而且會遮擋部分頁面內容,著實有些不太友好。
另一方面,alert的偵錯訊息,必須在程式邏輯中加入類似"alert(xxxxx)"這樣的語句,才能正常運作,且alert會阻礙頁面的繼續渲染。這就意味著開發人員調試完成後,必須手動清除這些偵錯程式碼,實在有些麻煩。
所以,新一代的瀏覽器Firefox、Chrome,包括IE,都相繼推出了JS調試控制台,支持使用類似"console.log(xxxx)"的形式,在控制台打印調試信息,而不直接影響頁面顯示。以IE為例,它看起來像這樣:
好吧,再見醜陋的alert彈出框。而以Chrome瀏覽器為首的後起之秀,為Console擴展了更豐富的功能:
你以為這樣就滿足了? Chrome開發團隊的想像力實在不得不讓人佩服:
好了,稍微多說了一點點題外話。總之,控制台以及瀏覽器內建Console物件的出現,為前端開發調試帶來了極大的便利。
有人會問,這樣的偵錯程式碼不一樣需要在調試完成後進行清理嗎?
關於這個問題,如果在使用console物件之前先進性存在性驗證,其實不刪除也不會對業務邏輯造成破壞。當然,為了程式碼整潔,在調試完成後,還是應盡可能刪除這些與業務邏輯無關的偵錯程式碼。
3、JS斷點除錯
斷點,偵錯器的功能之一,可以讓程式中斷在需要的地方,以便方便其分析。也可以在一次調試中設定斷點,下一次只需讓程式自動運行到設定斷點位置,便可在上次設定斷點的位置中斷下來,極大的方便了操作,同時節省了時間。 ——百度百科
JS斷點調試,即在瀏覽器開發者工具中為JS程式碼新增斷點,讓JS執行到某一特定位置停住,方便開發者對該處程式碼段的分析與邏輯處理。為了能夠觀察到斷點偵錯的效果,我們預先隨意準備一段JS程式碼:
#程式碼很簡單,就是定義一個函數,傳入兩個數,分別加上一個亂七八糟的隨機整數後,再回傳兩個數的總和。以Chrome開發者工具為例,我們來看看JS斷點調試的基本方法。
3.1、Sources斷點
首先,測試程式碼中我們透過上圖console的輸出結果可以看出程式碼應該是正常運作了,但為什麼是應該呢?因為函數中加了一個隨機數,而最終結果是否真的是正確的呢?這是毫無意義的猜想,但假設我現在就是要驗證一下:函數傳入的兩個數、被加的隨機數,以及最終的總和。那該怎麼操作呢?
方法一,前面講過最普通的,無論使用alert還是console,我們可以這麼來驗證:
從上圖發現,我們在在程式碼中新增了三行console程式碼,用以列印我們關心的資料變量,而最終我們從控制台(Console面板)中的輸出結果,可以很清楚的驗證整個計算過程是否正常,進而達到我們題設的驗證要求。
方法二,方法一的驗證過程存在很明顯的弊端就是,增加了許多冗餘程式碼,接下來我們看一下使用斷點進行驗證,是否更加方便,先看一個如何加斷點,以及斷點後是什麼效果:
如圖,給一段程式碼新增斷點的流程是"F12(Ctrl Shift I)開啟開發工具"—"點擊Sources選單"——"左側樹中找到對應檔案"——"點擊行號列"即完成在目前行新增/刪除斷點操作。當斷點加入完畢後,刷新頁面JS執行到斷點位置停住,在Sources介面會看到目前作用域中所有變數和值,只需對每個值進行驗證即可完成我們題設驗證要求。
那問題來了,仔細的朋友會發現當我的程式碼執行到斷點的時候,顯示的變數a和b的值是已經進行過加法運算後的,我們看不到呼叫sum函數時初始傳入的10和20。那該怎麼辦呢?這就要回過頭來先學習一下斷點調試的一些基礎了。我們打開Sources面板後其實會在介面中看到如下內容,我們跟著滑鼠軌跡逐一看看都是什麼意思:
從左到右,各個圖示表示的功能分別為:
Pause/Resume script execution:暫停/復原腳本執行(程式執行到下一個斷點停止)。
Step over next function call:執行到下一步的函數呼叫(跳到下一行)。
Step into next function call:進入目前函數。
Step out of current function:跳出目前執行函數。
Deactive/Active all breakpoints:關閉/開啟所有斷點(不會取消)。
Pause on exceptions:異常情況自動斷點設定。
到此,斷點調試的功能鍵介紹得差不多了,接下來我們就可以一行一行去看我們的程式碼,查看每一行執行完畢之後,我們各個變數的變化情況了,如下圖所示:
如上,我們可以看到a、b變數從最初值,到中間加上隨機值,再到最後計算總和並輸出最終結果的整個過程,完成題設驗證要求不在話下。
其餘幾個功能鍵,我們稍微改動一下我們的測試程式碼,用一張gif圖來示範他們的使用方法:
這裡需要注意一點,直接在程式碼區列印變數值的功能是在較新版本的Chrome瀏覽器中才新增的功能,如果你還在使用較老版本的Chrome瀏覽器,可能無法直接在斷點的情況下查看變數訊息,此時你可以將滑鼠移到變數名上短暫停頓則會出現變數值。也可以用滑鼠選取變數名稱,然後右鍵"Add to watch"在Watch面板查看,此方法同樣適用於表達式。此外,你也可以在斷點情況下,切換到Console面板,直接在控制台輸入變數名稱,回車查看變數資訊。這部分比較簡單,考慮篇幅問題,不在做圖片示範。
3.2、Debugger斷點
所謂的Debugger斷點,其實是我自己給它命名的,專業術語我也不知道怎麼說。具體的說就是透過在程式碼中加入"debugger;"語句,當程式碼執行到該語句的時候就會自動斷點。接著的操作就跟在Sources面板加入斷點調試幾乎一模一樣,唯一的差別在於調試後需要刪除該語句。
既然除了設定斷點的方式不一樣,功能和Sources面板添加斷點效果一樣,那麼為什麼還會存在這種方式呢?我想原因應該是這樣的:我們在開發中偶爾會遇到非同步載入html片段(包含內嵌JS程式碼)的情況,而這部分JS程式碼在Sources樹種無法找到,因此無法直接在開發工具中直接新增斷點,那麼如果想為非同步載入的腳本加入斷點,此時"debugger;"就發揮作用了。我們直接透過gif圖看看他的效果:
4、DOM斷點調試
DOM斷點,顧名思義就是在DOM元素上加入斷點,進而達到調試的目的。而在實際使用中斷點的效果最終還是落地到JS邏輯之內。我們依序來看每一種DOM斷點的具體效果。
4.1、當節點內部子節點變化時斷點(Break on subtree modifications)
在前端開發越來越複雜的今天,前端JS程式碼越來越多,邏輯越來越複雜,一個看似簡單的Web頁面,通常伴隨著大段大段的JS程式碼,涉及許多DOM節點增、刪、改的操作。難免會遇到直接透過JS程式碼很難定位程式碼段的情況,而我們卻可以透過開發者工具的Elements面板,快速定位到相關DOM節點,這時候透過DOM斷點定位腳本就顯得尤其重要了。具體我們還是透過gif示範來看一下:
上圖示範了對ul子節點(li)的增加、刪除以及交換順序操作觸發斷點的效果。但要注意的是,對子節點進行屬性修改和內容修改並不會觸發斷點。
4.2、當節點屬性改變時斷點(Break on attributes modifications)
另一方面,由於前端處理的業務邏輯越來越複雜,對有些資料的儲存依賴越來越強烈,而將暫存資料儲存在DOM節點的(自訂)屬性中,是許多情況下開發者優先選擇的方式。特別是在HTML5標準增強自訂屬性支援(例:dataset、data-*之類)之後,屬性設定應用越來越多,因此Chrome開發者工具也提供了屬性變更斷點支持,其效果大致如下:
此方式同樣需要注意,對子節點的屬性進行任何操作也不會觸發節點本身的斷點。
4.3、當節點被移除時斷點(Break on node removal)
這個DOM斷點設定很簡單,觸發方式很明確-當節點被刪除時。所以通常情況應該是執行"parentNode.removeChild(childNode)"語句的時候使用此方式。此方式使用不多。
前面介紹到的基本上是我們在日常開發中經常使用的調試手段,運用得當它們也幾乎能應對我們日常開發中的幾乎所有問題。但是,開發者工具也考慮到了更多的情況,提供更多的斷點方式,如圖:
5、XHR Breakpoints
這幾年前端開發發生了翻天覆地的變化,從當初的名不見經傳到如今的盛極一時,Ajax驅動Web富應用,移動WebApp單頁應用風生水起。這一切都離不開XMLHttpRequest對象,而"XHR Breakpoints"正是專為異步而生的斷點調試功能。
我們可以透過"XHR Breakpoints"右側的" "號碼為非同步斷點加入斷點條件,當非同步請求觸發時的URL滿足此條件,JS邏輯則會自動產生斷點。示範動畫中並沒有示範到斷點位置,這是因為,示範使用的是jQuery封裝好的ajax方法,程式碼已經過壓縮,看不到什麼效果,而事實上XHR斷點的產生位置是"xhr. send()"語句。
XHR斷點的強大之處是可以自訂斷點規則,這就意味著我們可以針對某一批、某一個,甚至所有非同步請求進行斷點設置,非常強大。但是,似乎這個功能在日常開發中用得不多,至少我用得不多。想想原因大概有兩點:其一,這類型的斷點調試需求在日常業務中本身涉及不多;其二,現階段的前端開發大多基於JS框架進行,最基本的jQuery也已經對Ajax進行了良好封裝,極少有人自己封裝Ajax方法,而專案為了減少程式碼體積,通常選擇壓縮後的程式碼庫,使得XHR斷點追蹤相對不那麼容易了。
6、Event Listener Breakpoints
事件監聽器斷點,即根據事件名稱進行斷點設定。當事件被觸發時,斷點到事件綁定的位置。事件監聽器斷點,列出了所有頁面及腳本事件,包括:滑鼠、鍵盤、動畫、計時器、XHR等等。極大的降低了事件方面業務邏輯的調試難度。
示範實例示範了當click事件觸發時和當setTimeout被設定時的斷點效果。實例顯示,當選取click事件斷點之後,兩個按鈕的點擊時都觸發了斷點,而當setTimeout被設定時,"Set Timer"斷點被觸發。
調試,是在專案開發中非常重要的環節,不僅可以幫助我們快速定位問題,還能節省我們的開發時間。熟練各種調試手段,定當為你的職業發展帶來諸多利益,但是,在如此多的調試手段中,如何選擇一個適合自己當前應用場景的,這需要經驗,需要不斷嘗試積累。
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
#以上是JS調試使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!