對(duì)于每一個(gè)程序員來(lái)說(shuō),在編程過(guò)程中出現(xiàn)bug和錯(cuò)誤是非常正常的一件事情,只要我們?cè)谏暇€之前排除問(wèn)題就可以了。今天,我們就一起來(lái)了解一下,JavaScript中的問(wèn)題都有哪些。
成都創(chuàng)新互聯(lián)公司是網(wǎng)站建設(shè)專(zhuān)家,致力于互聯(lián)網(wǎng)品牌建設(shè)與網(wǎng)絡(luò)營(yíng)銷(xiāo),專(zhuān)業(yè)領(lǐng)域包括網(wǎng)站建設(shè)、做網(wǎng)站、電商網(wǎng)站制作開(kāi)發(fā)、重慶小程序開(kāi)發(fā)公司、微信營(yíng)銷(xiāo)、系統(tǒng)平臺(tái)開(kāi)發(fā),與其他網(wǎng)站設(shè)計(jì)及系統(tǒng)開(kāi)發(fā)公司不同,我們的整合解決方案結(jié)合了恒基網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗(yàn)和互聯(lián)網(wǎng)整合營(yíng)銷(xiāo)的理念,并將策略和執(zhí)行緊密結(jié)合,且不斷評(píng)估并優(yōu)化我們的方案,為客戶(hù)提供全方位的互聯(lián)網(wǎng)品牌整合方案!
調(diào)用棧的工作機(jī)制
在探討JS中的錯(cuò)誤之前,我們必須理解調(diào)用棧(CallStack)的工作機(jī)制,其實(shí)這個(gè)機(jī)制非常簡(jiǎn)單,如果你對(duì)這個(gè)已經(jīng)一清二楚了,可以直接跳過(guò)這部分內(nèi)容。
簡(jiǎn)單的說(shuō):函數(shù)被調(diào)用時(shí),就會(huì)被加入到調(diào)用棧頂部,執(zhí)行結(jié)束之后,就會(huì)從調(diào)用棧頂部移除該函數(shù),這種數(shù)據(jù)結(jié)構(gòu)的關(guān)鍵在于后進(jìn)先出,即大家所熟知的LIFO。比如,當(dāng)我們?cè)诤瘮?shù)y內(nèi)部調(diào)用函數(shù)x的時(shí)候,調(diào)用棧從下往上的順序就是y-x。
Error對(duì)象及錯(cuò)誤處理
當(dāng)代碼中發(fā)生錯(cuò)誤時(shí),我們通常會(huì)拋出一個(gè)Error對(duì)象。Error對(duì)象可以作為擴(kuò)展和創(chuàng)建自定義錯(cuò)誤類(lèi)型的原型。Error對(duì)象的prototype具有以下屬性:
constructor_負(fù)責(zé)該實(shí)例的原型構(gòu)造函數(shù);
message_錯(cuò)誤信息;
name_錯(cuò)誤的名字;
上面都是標(biāo)準(zhǔn)屬性,有些JS運(yùn)行環(huán)境還提供了標(biāo)準(zhǔn)屬性之外的屬性,如Node.js、Firefox、Chrome、Edge、IE10、Opera和Safari6+中會(huì)有stack屬性,它包含了錯(cuò)誤代碼的調(diào)用棧,接下來(lái)我們簡(jiǎn)稱(chēng)錯(cuò)誤堆棧。錯(cuò)誤堆棧包含了產(chǎn)生該錯(cuò)誤時(shí)完整的調(diào)用棧信息。如果您想了解更多關(guān)于Error對(duì)象的非標(biāo)準(zhǔn)屬性,我強(qiáng)烈建議你閱讀MDN的這篇文章。
拋出錯(cuò)誤時(shí),你必須使用throw關(guān)鍵字。為了捕獲拋出的錯(cuò)誤,則必須使用trycatch語(yǔ)句把可能出錯(cuò)的代碼塊包起來(lái),catch的時(shí)候可以接收一個(gè)參數(shù),該參數(shù)就是被拋出的錯(cuò)誤。與Java中類(lèi)似,JS中也可以在trycatch語(yǔ)句之后有finally,不論前面代碼是否拋出錯(cuò)誤finally里面的代碼都會(huì)執(zhí)行,這種語(yǔ)言的常見(jiàn)用途有:在finally中做些清理的工作。
錯(cuò)誤堆棧的裁剪
Node.js才支持這個(gè)特性,通過(guò)Error.captureStackTrace來(lái)實(shí)現(xiàn),Error.captureStackTrace接收一個(gè)object作為1個(gè)參數(shù),以及可選的function作為2個(gè)參數(shù)。IT培訓(xùn)認(rèn)為其作用是捕獲當(dāng)前的調(diào)用棧并對(duì)其進(jìn)行裁剪,捕獲到的調(diào)用棧會(huì)記錄在1個(gè)參數(shù)的stack屬性上,裁剪的參照點(diǎn)是2個(gè)參數(shù),也就是說(shuō),此函數(shù)之前的調(diào)用會(huì)被記錄到調(diào)用棧上面,而之后的不會(huì)。
什么是Java程序員呢?Java程序員是這幾年出現(xiàn)的,他們的著裝經(jīng)常被吐槽,沒(méi)有人能夠get到他的笑點(diǎn),總是讓人感覺(jué)到莫名其妙,這就是很多人眼中的程序員。程序員在進(jìn)行軟件開(kāi)發(fā)的時(shí)候,會(huì)存在一些錯(cuò)誤的問(wèn)題,學(xué)會(huì)避免是非常關(guān)鍵的。下面電腦培訓(xùn)為大家介紹一下。
1、改一行代碼,不會(huì)影響其他功能
做任何事情誠(chéng)意是非常關(guān)鍵的,在不認(rèn)真的情況下任何事情都是做不好的。如果隨意改動(dòng)代碼,在連接數(shù)據(jù)庫(kù)的時(shí)候會(huì)出現(xiàn)很多問(wèn)題。想要成為一名合格的程序員,對(duì)代碼的嚴(yán)謹(jǐn)性是非常關(guān)鍵的。
2、不考慮自身問(wèn)題
在進(jìn)行軟件開(kāi)發(fā)的過(guò)程中,存在問(wèn)題是不可避免的,如何面對(duì)和處理問(wèn)題才是最關(guān)鍵的。如果在遇到問(wèn)題的時(shí)候一直認(rèn)為是電腦的問(wèn)題,這樣想法想要成為合格的程序員是不可能的。IT培訓(xùn)認(rèn)為硬件問(wèn)題是比較少的,不能很好的解決自己的問(wèn)題想要成功是不可能的。
3、使用臨時(shí)的方法
臨時(shí)方法并不是解決問(wèn)題的最好方法,在進(jìn)行編程的過(guò)程中,由于可能出現(xiàn)的問(wèn)題比較多,如果使用臨時(shí)辦法,最終可能會(huì)演變?yōu)橛谰玫霓k法,這對(duì)于程序員來(lái)說(shuō),北大青鳥(niǎo)認(rèn)為是非常避諱的解決方法。
4、以后在給代碼添加注釋
習(xí)慣是需要在生活中不斷養(yǎng)成的,好的習(xí)慣是成功的墊腳石。在進(jìn)行代碼書(shū)寫(xiě)的時(shí)候也應(yīng)該有一個(gè)好的習(xí)慣,如果只會(huì)一味地推脫,很難讓自己前進(jìn)。
5、測(cè)試過(guò),沒(méi)有BUG
有的程序員永遠(yuǎn)不承認(rèn)自己存在問(wèn)題,代碼存在BUG是很正常的,就算進(jìn)行測(cè)試之后也會(huì)出現(xiàn)同樣的問(wèn)題。在程序出現(xiàn)問(wèn)題的時(shí)候不要一味的認(rèn)為是使用而導(dǎo)致的,北大青鳥(niǎo)云南計(jì)算機(jī)學(xué)院認(rèn)為,作為程序員,應(yīng)該解決所有存在的問(wèn)題。
相信作為程序員的我們?cè)趯?duì)程序進(jìn)行編譯過(guò)程中經(jīng)常會(huì)遇到錯(cuò)誤,或者在運(yùn)行過(guò)程中出現(xiàn)錯(cuò)誤,在這里主要跟大家談?wù)劷?jīng)常遇到的一些異常與錯(cuò)誤,以及解決辦法。
異常是指程序在編譯或運(yùn)行過(guò)程出現(xiàn)的錯(cuò)誤。
在java.lang包中Throwable包含了所有的異常。
Error (錯(cuò)誤) 和Exception(異常)
(1)Error(錯(cuò)誤)
一旦發(fā)生無(wú)法修復(fù),但可以避免發(fā)生。
常見(jiàn)錯(cuò)誤類(lèi):
IOError:I/O錯(cuò)誤,當(dāng)發(fā)生嚴(yán)重的I/O錯(cuò)誤時(shí),拋出此錯(cuò)誤。
VirtualMachineError?:虛擬機(jī)錯(cuò)誤,當(dāng) Java 虛擬機(jī)崩潰或用盡了它繼續(xù)操作所需的資源時(shí),拋出該錯(cuò)誤。
StackOverflowError:棧內(nèi)存滿(mǎn)了,當(dāng)應(yīng)用程序遞歸太深而發(fā)生堆棧溢出時(shí),拋出該錯(cuò)誤。
OutofMemoryError:堆內(nèi)存滿(mǎn)了,因?yàn)閮?nèi)存溢出或沒(méi)有可用的內(nèi)存提供給垃圾回收器時(shí),Java 虛擬機(jī)無(wú)法分配一個(gè)對(duì)象,這時(shí)拋出該異常。
以上是一些常見(jiàn)的錯(cuò)誤,在Error類(lèi)中還有一些別的錯(cuò)誤(參照文件Java.lang.Throwable.Error).
(2)Exception(異常)
一旦發(fā)生,可以捕獲并處理,不會(huì)導(dǎo)致程序終止,有時(shí)可以避免有時(shí)無(wú)法避免。
異常的分類(lèi):
1.編譯時(shí)異常(需要強(qiáng)制處理)?????? 2.運(yùn)行時(shí)異常(不需要強(qiáng)制處理)
常見(jiàn)的異常有:
IOException:輸入輸出流異常
FileNotFoundException:文件找不到的異常
ClassNotFoundException:類(lèi)找不到的異常
DataFormatException:數(shù)據(jù)格式化異常
NoSuchFieldException:沒(méi)有匹配的屬性異常
NoSuchMethodException:沒(méi)有匹配的方法異常
SQLException:數(shù)據(jù)庫(kù)操作異常
TimeoutException:執(zhí)行超時(shí)異常
常見(jiàn)的運(yùn)行時(shí)異常:
RuntimeException:運(yùn)行時(shí)異常
NullPointerException:空指針異常
ArrayIndexOutofBoundsException:數(shù)組越界異
ClassCastException:類(lèi)型轉(zhuǎn)換異常
IllegalArgumentException:非法的參數(shù)異常
InputMismatchException:輸入不匹配
以上是常見(jiàn)的一些異常,另外還有別的異常,參見(jiàn)文件:Java.lang.Throwable.Exception
既然我們常常會(huì)遇到一些異常,那我們?nèi)绾蝸?lái)處理這些異常就是一個(gè)急需解決的事情。
(1) 如何處理編譯時(shí)異常?
方法一:將需要處理的代碼塊放在一個(gè)try...catch...中
try{
//需要處理異常的代碼
}catch(XXXException ef){
ef.printStackTrace();
}
我們方法一就是要將我們不確定的代碼放入try......catch中,先進(jìn)行try一下,如果沒(méi)有異常,則不會(huì)觸發(fā)catch,沒(méi)有輸出,一旦出現(xiàn)異常,那么catch就會(huì)工作,在catch中捕獲異常信息,根據(jù)異常信息進(jìn)行補(bǔ)救措施。
如以下代碼:
方法二:在出現(xiàn)異常的方法上直接向上拋出異常,throws
void ff() throws XXXException{
}
將出現(xiàn)的異常的代碼中,放入如上的方法中,就會(huì)將異常拋給該方法的上一級(jí),在主函數(shù)上繼續(xù)向上拋,最終拋給JVM java虛擬機(jī),讓JVM來(lái)解決該問(wèn)題。
如代碼:
注意:在catch和throws的時(shí)候如果不確定是什么異常,就直接寫(xiě)一個(gè)Exception.
(2) 如何處理運(yùn)行時(shí)異常?
1.一般情況下,運(yùn)行時(shí)異常是不用處理的?
2.在某些情況下,如果對(duì)發(fā)生異常的結(jié)果進(jìn)行處理,也可以對(duì)運(yùn)行時(shí)異常進(jìn)行try...catch...
以上就是一些我們處理編譯時(shí)異常和運(yùn)行時(shí)異常的方法。
在程序出現(xiàn)異常時(shí),有時(shí)候我們可以自定義異常,以便我們能夠發(fā)現(xiàn)是什么異常。
那么如何自定義異常??
1.當(dāng)運(yùn)行時(shí),程序出現(xiàn)意外,可以拋出異常對(duì)象來(lái)結(jié)束程序
如:
//拋出運(yùn)行時(shí)異常對(duì)象
RuntimeException ef = new RuntimeException("下標(biāo)越界!index:"+index+" ,size:"+size());
throw ef;
2.對(duì)于編譯時(shí)異常,同樣可以拋出異常對(duì)象
但在方法定義時(shí)候必須加上throws
如:
public void test(int t) throws Exception{
if (t 0 || t 100) {
Exception ef = new Exception("數(shù)據(jù)錯(cuò)誤");
throw ef;
}
}
例如:
運(yùn)行結(jié)果:
從結(jié)果可以看出,我們?cè)谳斎霐?shù)據(jù)的時(shí)候出現(xiàn)錯(cuò)誤,這樣通過(guò)自定義異常能夠讓我們更直接快速的找到運(yùn)行或編譯時(shí)的異常。
在上述中我們分別提到了三種throw,分別是Throwable,Throws以及throw,那么到底三者有什么區(qū)別?
Throwable:是指在在Java.lang包中的一個(gè)類(lèi),其包含了所有的異常和錯(cuò)誤,其中類(lèi)Error和Exception 是它
的子類(lèi)。
Thows:是指在解決編譯時(shí)異常,將方法中異常拋給上一級(jí),在方法后面要加Throw Exception來(lái)進(jìn)行拋。
throw:是指在自定義異常時(shí),如果方法出現(xiàn)異常,那么將作為引用方法的對(duì)象拋出。即拋出異常。