成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

前端必看!極具提效的網(wǎng)頁 JS 調(diào)試技巧

開發(fā) 前端
本文講解如何使用瀏覽器提供的工具進行 JS 代碼的斷點調(diào)試。

大家好,我是前端西瓜哥。本文講解如何使用瀏覽器提供的工具進行 JS 代碼的斷點調(diào)試。

debugger

在代碼中需要打斷點的地方,加上 debugger,表示一個斷點。瀏覽器代碼執(zhí)行到該位置時,會停下來,進入調(diào)試模式。

示例代碼:

function a() {
let a_var = 'a';
b(a_var);
}

function b(a_var_from_a) {
debugger;
console.log(global_var);
let b_var = 'b';
c();
}

function c() {
let c_var = 'c';
}

let module_var = 'module';
var global_var = 'global';

a();

整體就是調(diào)用 a,然后 a 調(diào)用 b,b 調(diào)用 c,然后有各種作用域的變量。

記得打開開發(fā)者工具面板,沒打開的話,debugger 會靜默失敗。

下面是斷點后的樣子。

圖片

現(xiàn)在是 a 函數(shù)調(diào)用了 b 函數(shù),b 函數(shù)調(diào)用的時候用 debugger 加了個斷點,于是我們就停在這里了。

此時上下文狀態(tài)和調(diào)用站會保留著,方便我們排查是什么分支導(dǎo)致變量狀態(tài)錯誤,比如一個錯誤的條件判斷,讓一個為 null 的變量沒能變成一個普通對象,導(dǎo)致訪問它的屬性報錯。

手動打斷點

在對應(yīng)的行號點一下就可以了,相當(dāng)于加了個 debugger 關(guān)鍵字。

圖片

刷新頁面后,手動打的斷點還會保留。

調(diào)用棧信息

首先是函數(shù)調(diào)用棧信息。

圖片

調(diào)用的起始端是一個匿名函數(shù),沒有名字的函數(shù)都會顯示 anonymouse,這里是 script 最外層的直接調(diào)用,所以沒有名字。我本人建議多給匿名函數(shù)起個名字,可讀性會更好。但如果你有起名困難癥,不起也好。

匿名函數(shù),然后調(diào)用了函數(shù) a,函數(shù) a 再調(diào)用了函數(shù) b,然后停下了。之后還會調(diào)用 c。

看到 b 旁邊的藍色箭頭沒,它表示我們 正在觀測哪個函數(shù)的上下文,默認會選擇棧頂。

你可以用光標(biāo)選擇你要觀測的函數(shù)下的變量,并且會高亮對應(yīng)的代碼。

圖片

作用域

我們看看某個函數(shù)的函數(shù)作用域的上下文。

找到 Scope 這個標(biāo)簽頁,目前我們可以看到有三種類型:Local、Script 和 Global。

首先是 Local,本地作用域。這里對應(yīng) b 函數(shù)的上下文,可以看到(1)傳入的變量,(2)函數(shù)內(nèi)部聲明的變量,以及 (3)this 值。

然后是 Script,表示一個模塊文件的最外層變量,和全局變量不同,只能被模塊文件內(nèi)的文件的代碼訪問。

最后是 Global,全局作用域。

圖片

再補充一個比較常見的閉包作用域。如果一個函數(shù)是通過閉包產(chǎn)生的,那在 Local 和 Script 還會有一個閉包作用域。

圖片

在函數(shù)中訪問一個變量,其實就是沿著這條鏈路去查找最先找到的那個,如果找不到就會拿到 undefined。

當(dāng)然除了這些,還有不少,比如塊作用域(Block)、捕獲作用域(Catch Block)、Eval 作用域、With 塊作用域等,篇幅原因,不一一介紹了。

執(zhí)行下一步

實際我們還要看看代碼是否如預(yù)期進入我們希望的分支并拿到正確的值,所以需要 讓代碼一點點執(zhí)行下去,觀察狀態(tài)的變化。

瀏覽器提供了各種執(zhí)行下一步代碼的方式。

圖片

我們一個個過一遍。

Resume 恢復(fù)腳本執(zhí)行

首先是最左邊這個 矩形+三角形 的藍色按鈕,它表示 結(jié)束當(dāng)前斷點,恢復(fù)腳本運行。

圖片

但如果往下執(zhí)行,又遇到一個斷點,那又會進入調(diào)試模式。

于是在長循環(huán)的情況下,就出不來了(悲)。

圖片

這時候惱羞成怒的西瓜哥有個辦法,長按這個按鈕,然后出現(xiàn)一個停止按鈕,點它會 結(jié)束所有的斷點

或者更常見的做法是,只在特定判斷條件下的打斷點,比如:

todoItems.forEach(item => {
// item 不可能為 null,我們來看看發(fā)生甚么事了
if (!item) {
debugger;
}
// ...
})

Step over 跳過下一個函數(shù)

然后是跳過下一個函數(shù)。就是遇到下一個要執(zhí)行的函數(shù),就不進去了,執(zhí)行完它繼續(xù)往下運行。

圖片

為什么要跳過函數(shù)?因為函數(shù)里面有很多代碼,或者里面又調(diào)用了其他函數(shù),要走好久才能回到當(dāng)前函數(shù)。

如果我們只是想看當(dāng)前函數(shù)的完整邏輯,那就跳過其下的函數(shù)執(zhí)行。

Step into 進入下一個函數(shù)

如果走著走著遇到一個函數(shù),進入這個函數(shù)。

圖片

注意,瀏覽器環(huán)境自帶的 api 方法是進不去的。

Step out 跳出當(dāng)前函數(shù)

如果你不想再看當(dāng)前函數(shù)的執(zhí)行了,想回到調(diào)用它的函數(shù),就可以選擇這個方式。

圖片

Step 下一步

就是普通的下一步,它會嚴格遵守代碼的執(zhí)行順序,比較常用。

圖片

Step into 和 Step 的區(qū)別

Step into 和 Step 在大體的表現(xiàn)上有些相同,遇到函數(shù)是會進入函數(shù)內(nèi)部的,但在異步代碼下,行為有一些不同。

Step into 在遇到一個異步代碼的回調(diào)函數(shù),會直接掛起并讓后面的同步代碼繼續(xù)跑,直到這個異步函數(shù)被執(zhí)行,然后進入這個函數(shù)。

而 Step 則符合代碼的執(zhí)行順序,先執(zhí)行后面的同步代碼,然后再執(zhí)行異步函數(shù)。

我們用一個實例演示一下。代碼為:

window.onclick = () => {
debugger;
setTimeout(() => {
console.log('inside');
console.log('p1', performance.now() / 1000);
}, 2000);
console.log('p2', performance.now() / 1000);
console.log('p3', performance.now() / 1000);
};

Step into 的表現(xiàn):

圖片

可以看到,Step into 會等待異步函數(shù)被執(zhí)行,才進入到函數(shù)內(nèi)部,然后停在它的首行。

然后是 Step:

圖片

Step 遵循正常的代碼執(zhí)行過程順序:先走完同步代碼,然后再進入異步代碼。

直接跳到某一行

我們可能想直接跳到中間的一連串邏輯,直接走到后面的某一行,對此我們可以手動跳轉(zhuǎn)。

具體做法是行號右鍵選擇 continue to here。

需要注意,這個地方必須是和當(dāng)前位置在同一個函數(shù)下,否則會等價于執(zhí)行了 Resume。

圖片

其他

關(guān)閉斷點功能

關(guān)閉斷點功能(deactivate breakpoint)。

開啟這個,斷點在打開開發(fā)者工具的條件下無效。

圖片

上一篇文章西瓜哥說了一個用定時器不斷執(zhí)行 debugger 的方式,防止別人點點點看代碼是怎么執(zhí)行的。但這只能防小白,我們把這個開了就無視 debugger 關(guān)鍵字了。

報錯時斷點

代碼報錯時,我們希望知道報錯那瞬間的上下文。

此時我們可以開啟這個功能,在報錯且沒有被捕獲時,瀏覽器會給你打一個斷點,然后你可以看看哪個變量出了問題。

圖片

還可以勾選這個 Pause on caught exceptions,效果是錯誤被捕獲時,打斷點:

圖片

結(jié)尾

光說不練假把式,西瓜哥建議你自己嘗試一番。

編程是一個實操性很強的學(xué)科,要自己動手調(diào)試,這樣才能更好地理解掌握。

責(zé)任編輯:姜華 來源: 前端西瓜哥
相關(guān)推薦

2022-04-28 12:17:26

瀏覽器連字符hyphens

2020-07-22 13:50:39

shell命令前端

2017-04-25 17:15:00

2023-11-22 19:10:42

前端父應(yīng)用文案

2022-07-08 11:18:33

前端實踐自動化

2025-02-20 09:00:00

字符串JavaScript代碼

2015-06-29 13:44:16

前端網(wǎng)頁渲染技巧

2024-09-02 08:03:23

2017-10-17 11:51:59

移動端調(diào)試網(wǎng)頁Erdua

2021-09-23 05:57:52

Vscode JS 項目

2020-05-20 19:38:11

前端js調(diào)試工具

2025-02-26 12:00:00

JavaScript代碼開發(fā)

2022-10-20 08:34:09

圖像算法商品

2023-12-27 18:15:42

組裝式生態(tài)提效開發(fā)中心

2017-12-08 11:28:58

MySQL性能調(diào)優(yōu)技巧

2022-08-26 09:51:33

Web前端自動化

2021-02-26 14:35:23

開發(fā)技能代碼

2025-02-07 12:58:33

python自動化腳本

2021-02-27 10:58:25

基礎(chǔ)組件React
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 日本一区二区三区免费观看 | 日韩一区二区黄色片 | 国产一区二区三区在线 | 视频精品一区 | 国产视频不卡一区 | 精品国产一区二区在线 | 91在线视频观看免费 | 狠狠干影院| 欧美一区二区在线观看 | 国产精品久久精品 | 日韩一区二区三区在线播放 | 国产免费一级一级 | 嫩草视频在线看 | 欧美日一区二区 | 欧美一区二区三区 | 精品福利在线视频 | 欧美一级黄色片免费观看 | 在线国产视频 | 国产剧情一区 | 欧美精品欧美精品系列 | 欧美黄色网 | 欧美日韩精品久久久免费观看 | 免费黄色在线观看 | 欧美日韩在线高清 | 国产精品久久久久久久久免费软件 | 国产精品综合一区二区 | 91精品国产自产精品男人的天堂 | 亚洲综合视频 | 综合久久综合久久 | 精品一区二区三区在线播放 | 国产日韩欧美精品 | 99精品国产一区二区三区 | 一区二区三区在线电影 | 欧美日韩在线国产 | av电影手机版 | 一区二区三区免费在线观看 | 国产一二三区精品视频 | 久久久久久av | 一区二区福利视频 | 日韩成人高清 | 91精品国产91久久久久久吃药 |