try{?//正常執(zhí)行?}catch(e/*你感覺(jué)會(huì)出錯(cuò)的 錯(cuò)誤類型*/){?// 可能出現(xiàn)的意外 eg:用戶自己操作失誤 或者 函數(shù)少條件 不影響下面的函數(shù)執(zhí)行?// 有時(shí)也會(huì)用在 比如 focus() 但可惡的ie有可能會(huì)第一次沒(méi)有focus事件 再讓他執(zhí)行一次?// 有時(shí)一些不是bug的bug 在ie上 他要求必須加上 catch 哪怕就一個(gè)空catch 以前在ie8上遇到過(guò)這個(gè)js問(wèn)題?}
try catch的使用,永遠(yuǎn)應(yīng)該放在你的控制范圍之內(nèi),而不應(yīng)該防范未知的錯(cuò)誤。也就是說(shuō)你很清楚知道這里是有可能”出錯(cuò)“的,而且你很清楚知道什么前提下會(huì)出錯(cuò),你就是要故意利用報(bào)錯(cuò)信息來(lái)區(qū)分錯(cuò)誤,后續(xù)的程序會(huì)解決所有的出錯(cuò),讓程序繼續(xù)執(zhí)行。
如果讓用戶先發(fā)現(xiàn)你根本沒(méi)預(yù)料到的錯(cuò)誤,而不是你先發(fā)現(xiàn)錯(cuò)誤,你是失職的。
大多數(shù)情況下,try catch適用于兩種場(chǎng)合:
1、瀏覽器原罪的場(chǎng)合:也就是兼容性場(chǎng)合,因?yàn)闉g覽器兼容性不是程序員能改正的,所以只能try catch:由于不同瀏覽器的報(bào)錯(cuò)提示是不一樣的,根據(jù)捕獲的瀏覽器的報(bào)錯(cuò)提示判斷用戶的瀏覽器,然后做出對(duì)應(yīng)的措施,這時(shí)候使用try catch是巧妙的辦法,如果用if就比較笨拙,因?yàn)閕f通常只能反饋真或假,不能直接反饋瀏覽器的報(bào)錯(cuò)內(nèi)容。
2、考慮如下代碼。window.a.b是非法的,再跟2對(duì)比就沒(méi)有意義,這樣非法的條件,在try catch中仍可以繼續(xù)運(yùn)行下去。但在if中window.a.b已經(jīng)報(bào)錯(cuò),整個(gè)頁(yè)面都會(huì)壞掉。如果希望用if寫(xiě),那么必須先判斷window.a是否是合法的,window.a是合法的前提下再判斷window.a.b是不是合法的,如果也是合法的,再判斷window.a.b是否不等于2,這樣是不是很蠢?這時(shí)就體現(xiàn)出try catch的妙處了,程序不但知道window.a.b !== 2是假的,而且直接可以知道究竟哪一步就已經(jīng)是假的。
再想象一下,有一個(gè)變量是json.a.b.c,其中的a/b/c都可能是存在的也可能是不存在的,全看具體情況,這時(shí)候你簡(jiǎn)單的寫(xiě)if (json.a.b.c === 2) {...}是不行的,因?yàn)閖son.a.b就可能已經(jīng)是非法的,所以你如果用if,就要考慮a是不是非法的、a是合法前提下b是不是非法的,b是合法前提下c是不是非法的。但是json.a.b.c === 2在try中就可以直接寫(xiě),也就是說(shuō),我不關(guān)心究竟a/b/c誰(shuí)是非法的,我只關(guān)心json.a.b.c到底是不是等于2,不等于2或者任何一步出錯(cuò),對(duì)我來(lái)講沒(méi)有區(qū)別,反正都是不等于2,我不關(guān)心哪步出錯(cuò),而且程序不會(huì)壞掉。這是一種比較省心的寫(xiě)法。
另外注意,try catch不能做真假判斷,只能做非法判斷。也就是說(shuō):try {1 === 2},雖然1===2是假,但是是合法的,catch不會(huì)捕捉到錯(cuò)誤,也不會(huì)告訴你1 === 2到底是真是假。所以,寫(xiě)在try里的應(yīng)該是json.a.b.c而不是json.a.b.c === 2。究竟是不是等于2,是后面的事,是if干的事。簡(jiǎn)單說(shuō),try catch用于捕捉報(bào)錯(cuò),當(dāng)你不關(guān)心哪一步錯(cuò)誤,只關(guān)心有沒(méi)有錯(cuò),就用try catch。
try{window.a.b!==2}catch(err){alert(err)// 可執(zhí)行alert(123)// 可執(zhí)行}if(window.a.b!==2){alert("error")// 不執(zhí)行}alert(123);// 不執(zhí)行
最后,try catch在早期被各種語(yǔ)言的程序員濫用,try catch出現(xiàn)的場(chǎng)合被夸大了,事實(shí)上沒(méi)那么多適用場(chǎng)合。如果你的幾千行程序都沒(méi)用到try catch也是很正常的,尤其是用了jquery
1、事情還有得挽回,換條路走
try {
執(zhí)行某個(gè)邏輯
} catch (e) {
出問(wèn)題鳥(niǎo),換個(gè)邏輯執(zhí)行
}
2、體面的退出
try {
正常流程
} catch (e) {
彈個(gè)框告訴用戶不好意思出了點(diǎn)問(wèn)題
如果是用戶的錯(cuò)就告訴用戶什么地方錯(cuò)了
如果是程序的錯(cuò),就告訴用戶不好意思沒(méi)法執(zhí)行
}
3、
偶認(rèn)為,異常處理和錯(cuò)誤處理是兩個(gè)不同的概念。例如NodeJS里大多數(shù)error都是用來(lái)處理異常的,因?yàn)楫惓J遣豢杀苊獾模鐢?shù)據(jù)庫(kù)掛了,網(wǎng)絡(luò)錯(cuò)誤,你雖然知道有可能,但是不知道何時(shí)發(fā)生,這些異常你需要捕捉或者傳給上層。而錯(cuò)誤處理,則是一些基本的判定,可以從代碼級(jí)別避免其發(fā)生,可預(yù)知可推測(cè),如果發(fā)生了,不是系統(tǒng)問(wèn)題,而是你的程序有bug了。
對(duì)于NodeJS來(lái)說(shuō),兩種錯(cuò)誤都時(shí)刻需要注意,特別是系統(tǒng)錯(cuò)誤,因?yàn)椴豢深A(yù)知,需要大量代碼來(lái)catch錯(cuò)誤,傳遞錯(cuò)誤,最后統(tǒng)一處理。
而對(duì)于前端,系統(tǒng)錯(cuò)誤出現(xiàn)的場(chǎng)景相對(duì)來(lái)說(shuō)低得多,主要是一些io場(chǎng)景,大部分前端可能不太關(guān)心。而普通的錯(cuò)誤處理,則比較常見(jiàn),因?yàn)榍岸笋詈系奶囟ㄏ到y(tǒng)比較多,和這些系統(tǒng)操作的時(shí)候,數(shù)據(jù)和dom啊什么的大多是可預(yù)知的,跟系統(tǒng)錯(cuò)誤還是要區(qū)分開(kāi)的,一些錯(cuò)誤,需要你自己去吞并和處理,如果出現(xiàn)錯(cuò)誤,顯然是bug,而不是不可預(yù)知。