2.6 JavaScript調試工具
一直以來(lái),Java開(kāi)發(fā)過(guò)程的進(jìn)步與其調試架構是分不開(kāi)的,這種調試架構使在源代碼中一步一步地調試程序變得非常簡(jiǎn)單。當今的很多Java IDE都具有異常強大的調試環(huán)境,它們允許你調試標準的Java SE應用、部署到本地Java EE應用服務(wù)器上的應用,甚至是部署到遠程Java EE服務(wù)器上的應用。
調試傳統的JavaScript要比Java困難得多,因為JavaScript缺少一個(gè)高質(zhì)量的調試環(huán)境。這一缺陷現在得到了改善。作為基于Mozilla的瀏覽器(如Firefox)的擴展,Venkman JavaScript調試器提供了一個(gè)功能完整的JavaScript調試環(huán)境。
下面我們將簡(jiǎn)單介紹Venkman及其功能??梢栽趙ww.svendtofte.com/code/learning_venkman上找到一份更全面的教程。
使用Venkman
可以從www.mozilla.org/projects/venkman/獲得Venkman。Venkman的開(kāi)發(fā)始于2001年4月,由Robert Ginda發(fā)起。Venkman基于Mozilla的名為js/jsd的JavaScript調試API。js/jsd API構成了Netscape JavaScript調試器的基礎,后者可以用在Netscape瀏覽器的4.x系列版本中。
在安裝好Venkman之后,可以通過(guò)Firefox中的Tools→JavaScript Debugger菜單項啟動(dòng)它。圖2-17展示了Venkman的默認布局。
Venkman提供了非常多的信息,這些信息分別顯示在8個(gè)窗格中。默認布局中有一個(gè)較大的窗格用來(lái)顯示選中的源代碼。窗口的左邊垂直排列著(zhù)三個(gè)較小的窗格。在Source Code窗格下方是Venkman的命令行界面,它位于窗口的底部。
可以用鼠標拖動(dòng)每個(gè)窗口并把它們放置到主窗口的任意位置。還可以把一個(gè)窗格添加為另一個(gè)現有窗格的獨立標簽頁(yè)。例如,根據圖2-17,如果想要把Loaded Scripts標簽頁(yè)放置到Local Variables窗格中,只需把Loaded Scripts標簽頁(yè)拖放至Local Variables標簽頁(yè)即可。也可以把窗格從主窗口中分離出來(lái),只需單擊窗格標題欄左側的控制按鈕即可。再次單擊該控制按鈕就可以使窗格回到主窗口中。

圖2-17 Venkman的默認窗口布局
在使用Venkman的過(guò)程中,你會(huì )根據自己的需要經(jīng)常使用幾個(gè)面板。單擊窗格標題欄右側的×按鈕可以關(guān)閉不常用的窗格??梢酝ㄟ^(guò)選擇View→Show/Hide來(lái)重新打開(kāi)這些窗格。如果想恢復窗格布局的默認設置,只需在Interactive Session窗格中的命令行界面中輸入/restore-layout factory即可。
1. 查看已加載的腳本
啟動(dòng)Venkman后,它會(huì )識別瀏覽器窗口中當前頁(yè)面上所有可用的JavaScript。Venkman可以識別出在HTML頁(yè)面中使用<script>標簽嵌入的JavaScript以及使用<script src="js_file.js">標簽引入的外部JavaScript文件。
Venkman把當前可用的JavaScript顯示在Loaded Scripts窗格中。單擊每個(gè)文件邊上的加號可以打開(kāi)一個(gè)文件內部信息列表,它詳細列出了文件中所有可用的JavaScript函數以及這些函數出現在文件中的行號。另外,它還可以顯示函數所包含的代碼行號。在Loaded Scripts窗格中雙擊一個(gè)函數會(huì )在Source Code窗格中顯示該文件并直接滾動(dòng)到該函數所在的位置。
右鍵單擊Loaded Scripts窗格中的文件會(huì )為文件本身和文件中的JavaScript函數顯示出一些選項。對文件來(lái)說(shuō),這個(gè)右鍵菜單允許你執行如下一些操作,比如禁止調試eval和timeout聲明,禁止調試函數,以及禁止對函數進(jìn)行性能監控。對單個(gè)函數來(lái)說(shuō),這個(gè)右鍵菜單提供了禁止調試和禁止性能分析的功能。
2. 源代碼
Source Code窗格會(huì )列出當前文件的源代碼。文件的類(lèi)型可以是HTML、XHTML或JavaScript。Source Code窗格實(shí)現了標簽頁(yè)機制,因此可以一次打開(kāi)多個(gè)文件,每個(gè)文件都顯示在自己的標簽頁(yè)中。Venkman會(huì )使用一些簡(jiǎn)單的顏色顯示代碼,這樣可以提高可讀性。JavaScript關(guān)鍵字如function和var會(huì )顯示為粗體,字符串則會(huì )顯示為不同的顏色。窗格左側是文件的代碼行編號,再左側是用于設置斷點(diǎn)的側邊欄。
3. 斷點(diǎn)
Venkman支持兩種斷點(diǎn):硬(hard)斷點(diǎn)和將來(lái)(future)斷點(diǎn)。這與絕大多數調試環(huán)境都不太一樣,因此我們會(huì )討論這兩種斷點(diǎn)間的區別。
硬斷點(diǎn)就是你經(jīng)常在像Java這樣的現代編程語(yǔ)言中使用的斷點(diǎn)。它會(huì )指示Venkman在斷點(diǎn)處掛起程序的執行。在收到用戶(hù)的指示之前,程序不能繼續執行。在Venkman中,硬斷點(diǎn)總是設置在函數體內。
將來(lái)斷點(diǎn)與硬斷點(diǎn)類(lèi)似,它也指示Venkman在斷點(diǎn)處掛起JavaScript的執行。兩者的不同之處在于,將來(lái)斷點(diǎn)總是設置在函數體外。這些代碼會(huì )在瀏覽器加載它們之后立即執行。相反,函數體中的代碼則一直到該函數響應用戶(hù)的操作或事件時(shí)才會(huì )執行。
在很大程度上,大可不必在意硬斷點(diǎn)和將來(lái)斷點(diǎn)之間的區別。在大部分情況下,都會(huì )使用硬斷點(diǎn),它們應該與其他調試環(huán)境中的斷點(diǎn)具有相同的功能。
Venkman提供了一個(gè)列出所有當前斷點(diǎn)的窗口。當你調試的頁(yè)面在多個(gè)文件中含有多個(gè)斷點(diǎn)的時(shí)候,這就會(huì )非常方便。所有設置了斷點(diǎn)的文件都會(huì )顯示在Breakpoints窗格中,在每個(gè)文件下面會(huì )列出這個(gè)文件的所有斷點(diǎn)。
4. 分步執行代碼
設置好斷點(diǎn)之后,就可以開(kāi)始調試代碼了。Venkman會(huì )在遇到斷點(diǎn)時(shí)自動(dòng)掛起程序的執行。那時(shí),就可以控制腳本的執行了。你可以查看變量值,修改變量值,并繼續執行腳本,可以分步執行代碼或重新啟動(dòng)并完成執行過(guò)程。
在遇到斷點(diǎn)時(shí),Venkman為開(kāi)發(fā)人員提供了幾個(gè)用來(lái)分步執行代碼的選擇。一旦遇到斷點(diǎn),可以選擇Continue、Step Over、Step Into或Step Out。
Continue選項會(huì )重新啟動(dòng)腳本的執行。執行過(guò)程會(huì )一直繼續,直到遇到另一個(gè)斷點(diǎn)或腳本結束。當需要跟蹤一個(gè)問(wèn)題的位置時(shí),Continue屬性非常有用。你可以沿著(zhù)程序執行鏈設置多個(gè)斷點(diǎn),并且在每次遇到斷點(diǎn)的時(shí)候查看變量值以確定問(wèn)題是否已經(jīng)出現。一旦問(wèn)題出現了,就可以知道這個(gè)問(wèn)題是出現在當前斷點(diǎn)和前一個(gè)斷點(diǎn)之間,這樣就可以從那里繼續縮小錯誤出現的區域。Continue選項還可以用來(lái)調試迭代??梢栽诘哪程幵O置斷點(diǎn)并使用Continue選項一次一次地執行迭代代碼,并在每次掛起的時(shí)候檢查是否出現任何問(wèn)題。
Step Over功能可以使你避免進(jìn)入當前函數調用的函數。那個(gè)被調用的函數可能已經(jīng)被調試過(guò)了并且你知道問(wèn)題不在那兒,或者你就是不想進(jìn)入那個(gè)函數的代碼,因為你只關(guān)心當前函數。需要記住的是,越過(guò)一個(gè)函數并不會(huì )影響這個(gè)函數的執行;它只是表示你不打算一行一行地調試該函數。
Step Into選項和Step Over功能正好相反。Step Into會(huì )進(jìn)入一個(gè)被調用的函數,這樣就可以調試這個(gè)被調用的函數了。合理使用Step Over和Step Into可以幫助你確定錯誤的具體位置。
5. 局部變量列表
Local Variables窗格允許你在腳本運行時(shí)查看甚至修改變量的值。每當遇到斷點(diǎn)并掛起腳本執行時(shí),Local Variables窗格就會(huì )顯示當前作用域內的所有變量。
Local Variables窗格具有兩個(gè)頂級項:Scope和This。Scope指向程序執行的當前最近作用域內的所有變量。因為大多數JavaScript都會(huì )被編寫(xiě)為函數,所以這個(gè)最近作用域往往是函數作用域。例如,如果遇到了一個(gè)函數內的斷點(diǎn),那么Local Variables窗格中的Scope項就會(huì )指向該函數作用域內的所有變量——也就是在該函數中使用關(guān)鍵字var定義的任何變量。從技術(shù)上來(lái)說(shuō),函數可以訪(fǎng)問(wèn)那些定義在全局作用域內的變量(定義在函數體外的變量),但是它們不會(huì )顯示在當前變量作用域中。
Local Variables窗格中顯示的第二個(gè)頂級項是This項。This項指向關(guān)鍵字this指代的任何對象。如果在一個(gè)函數中遇到斷點(diǎn),而這個(gè)函數又是一個(gè)對象的一部分,那么this指代的就是當前對象的實(shí)例。正常情況下,this引用的是瀏覽器的window對象。需要注意的是,在全局作用域內定義的任何變量都會(huì )出現在This項下面。
局部變量列表還允許在運行時(shí)修改變量的值。這一功能非常強大,它可以幫助你測試不同變量值對腳本輸出的影響。當你覺(jué)得自己發(fā)現了一個(gè)問(wèn)題的時(shí)候,還可以使用這一功能修改變量的值,看看是否可以解決這個(gè)問(wèn)題。
右鍵單擊想要修改的變量值,在右鍵菜單中選擇Change Value。這會(huì )打開(kāi)一個(gè)提示窗口,可以在里面修改變量的值??梢栽谔崾敬翱谥休斎肴魏魏戏ǖ腏avaScript表達式,包括new Object()這樣的表達式。確保所有的字符串都加上了雙引號或單引號。記住,在提示窗口中還可以通過(guò)變量名引用其他變量。
聯(lián)系客服