javascript
html 中如何写js代码提示错误,javascript怎么进行错误处理?
在ES3之前js代碼執(zhí)行的過程中,一旦出現(xiàn)錯誤,整個js代碼都會停止執(zhí)行,這樣就顯的代碼非常的不健壯。從ES3開始,js也提供了類似的錯誤處理機(jī)制,從而讓js代碼變的更健壯,及時執(zhí)行的過程中出現(xiàn)了異常,也可以讓程序具有了一部分的異常恢復(fù)能力。
良好的錯誤處理機(jī)制可以讓用戶及時得到提醒,知道到底發(fā)生了什么事,因而不會驚慌失措。為此,作為開發(fā)人員,我們必須理解在處理JavaScript錯誤的時候,都有哪些手段和工具可以利用。
一,try-catch 語句
ECMA-262第3版引入了try-catch語句,作為JavaScript中處理異常的一種標(biāo)準(zhǔn)方式。基本的語法如下所示,顯而易見,這與Java中的try-catch語句是完全相同的:try {
//可能會導(dǎo)致錯誤的代碼
} catch (error) {
//在錯誤發(fā)生時怎么處理
}
也就是說,我們應(yīng)該把所有可能會拋出錯誤的代碼都放在try語句快中,而把那些用于錯誤處理的代碼放在catch塊中,例如:try {
window.someNonexistentFunction(); //調(diào)用不存在的函數(shù)
} catch (error) {
alert('An error happened!');
}
如果try塊中的任何代碼發(fā)生了錯誤,就會立即退出代碼執(zhí)行過程,然后接著執(zhí)行catch塊,此時,catch塊會接收到一個包含錯誤信息的對象。
與在其他語言中不同的是,即使你不想使用這個錯誤對象,也要給它起個名字。這個對象中包含的實(shí)際信息會因?yàn)g覽器而異,但共同的是有一個保存著錯誤信息的message屬性。
ECMA-262還規(guī)定了一個保存著錯誤類型的name屬性,當(dāng)前所有瀏覽器都支持這個屬性(Opera9之前的版本不支持這個屬性)。因此,在發(fā)生錯誤時,就可以像下面這樣實(shí)事求是地顯示瀏覽器給出的信息:try {
window.someNonexistentFunction(); //調(diào)用不存在的函數(shù)
} catch (error) {
alert(error.message);
}
這個例子在向用戶顯示錯誤信息時,使用了錯誤對象的message屬性,這個message屬性是唯一一個能保證所有瀏覽器都支持的屬性,除此之外,IE、Firefox、Safari、Chrome以及Opera都為事件對象添加了其他相關(guān)信息。
IE添加了與message屬性完全相同的description屬性,還添加了保存著內(nèi)部錯誤數(shù)量的number屬性。
Firefox添加了fileName、lineNumber和stack(包含棧跟蹤信息)屬性。
Safari添加了line(表示行號)、sourceId(表示內(nèi)部錯誤代碼)和sourceUrl屬性。
當(dāng)然,在跨瀏覽器編程時,最好還是只使用message屬性。
1,finally子句
雖然在try-catch語句中是可選的,但finally子句一經(jīng)使用,其代碼無論如何都會執(zhí)行。換句話說,try語句塊中的代碼全部正常執(zhí)行,finally子句會執(zhí)行;如果因?yàn)槌鲥e而執(zhí)行了catch語句塊,finally子句照樣還會執(zhí)行。
只要代碼中包含finally子句,則無論try或catch語句塊中包含什么樣的代碼——甚至return語句,都不會阻止finally子句的執(zhí)行。來看下面這個函數(shù):function testFinally() {
try {
return 2;
} catch (error) {
return 1;
} finally {
return 0;
}
}
testFinally(); //0
這個函數(shù)在try-catch語句的每一部分都放了一條return語句。表面上看,調(diào)用這個函數(shù)會返回2,因?yàn)榉祷?個return語句位于try語句塊中,而執(zhí)行該語句又不會出錯。
可是,由于最后還有一個finally子句,結(jié)果就會導(dǎo)致該return語句被忽略,也就是說,調(diào)用這個函數(shù)只能返回0,如果把finally子句拿掉,這個函數(shù)將返回2。
注:只要代碼中包含finally子句,那么無論try還是catch語句塊中的return語句都將被忽略。因此,在使用finally子句之前,一定要非常清楚你想要代碼怎么樣。
2,錯誤類型
執(zhí)行代碼期間可能會發(fā)生的錯誤有多種類型,每種錯誤都有對應(yīng)的錯誤類型,而當(dāng)錯誤發(fā)生時,就會拋出相應(yīng)類型的錯誤對象。ECMA-262定義了下列7種錯誤類型:
● Error
● EvalError
● RangeError
● ReferenceError
● SyntaxError
● TypeError
● URIError
其中,Error是基類型,其他錯誤類型都繼承自該類型,因此,所有錯誤類型共享了一組相同的屬性(錯誤對象中的方法全是默認(rèn)的對象方法)。Error類型的錯誤很少見,如果有也是瀏覽器拋出的;這個基類型的主要目的是供開發(fā)人員拋出自定義錯誤。
EvalError類型的錯誤是在使用eval()函數(shù)而發(fā)生異常時拋出。ECMA-262中對這個錯誤有如下描述:“表示全局函數(shù)eval的使用方式與其定義不相符。“除此之外,并沒有救到底什么情況會引發(fā)這種錯誤給出說明。在實(shí)際開發(fā)中碰到這種錯誤的可能性并不大。
RangeError類型的錯誤會在數(shù)值超出相應(yīng)范圍時觸發(fā)。例如,在定義數(shù)組時,如果指定了數(shù)組不支持的項(xiàng)數(shù)(如-20或Number.MAX_VALUE),就會觸發(fā)這種錯誤。下面是具體的例子:var items1 = new Array(-20); //VM77:1 Uncaught RangeError: Invalid array length(…)
var items2 = new Array(Number.MAX_VALUE); //VM79:1 Uncaught RangeError: Invalid array length(…)
JavaScript中經(jīng)常會出現(xiàn)這種范圍錯誤。
在找不到對象的情況下,會發(fā)生ReferenceError(這種情況下,會直接導(dǎo)致人所共知的“object expected"瀏覽器錯誤)。通常,在訪問不存在的變量時,就會發(fā)生這種錯誤,例如:var obj = x; //VM112:1 Uncaught ReferenceError: x is not defined(…) 在x未聲明的情況下拋出ReferenceError
至于SyntaxError,當(dāng)我們把語法錯誤的JavaScript字符串傳入eval()函數(shù)時,就會導(dǎo)致此類錯誤,例如:eval('a ++ b'); //VM114:1 Uncaught SyntaxError: Unexpected identifier(…)
如果語法錯誤的代碼出現(xiàn)在eval()函數(shù)之外,則不太可能發(fā)生SyntaxError,因?yàn)榇藭r的語法錯誤導(dǎo)致JavaScript代碼立即停止執(zhí)行。
TypeError類型在JavaScript中經(jīng)常用到,在變量中保存著意外的類型時,或者在訪問不存在的方法時,都會導(dǎo)致這種錯誤。錯誤的原因雖然多種多樣,但歸根結(jié)底還是由于在執(zhí)行特定于類型的操作時,變量的類型并不符合要求所致。下面來看幾個例子:
最常發(fā)生類型錯誤的情況,就是傳遞給函數(shù)的參數(shù)事先未經(jīng)檢查,結(jié)果傳入類型與預(yù)期類型不相符。
在使用encodeURI()或decodeURI(),而URI格式不正確時,就會導(dǎo)致URIError錯誤,這種錯誤也很少見,因?yàn)榍懊嬲f的這兩個函數(shù)的容錯性非常高。
利用不同的錯誤類型,可以熟悉更多有關(guān)異常的信息,從而有助于對錯誤作出恰當(dāng)?shù)奶幚?#xff0c;要想知道錯誤的類型,可以像下面這樣在try-catch語句的catch語句中使用instanceof操作符:try {
someFunction();
} catch (error) {
if (error instanceof TypeError) {
//處理類型錯誤
} else if (error instanceof ReferenceError) {
//處理引用錯誤
} else {
//處理其他類型的錯誤
}
}
在跨瀏覽器編程中,檢查錯誤類型是確定處理方式的最簡便途徑,包含在message屬性中的錯誤消息會因?yàn)g覽器而異。
3,try-catch語句執(zhí)行順序
看下面的例子:
執(zhí)行順序?yàn)?#xff1a;首先執(zhí)行try語句塊中的代碼,如果拋出異常,接著執(zhí)行catch語句塊中代碼,如果沒有異常,catch語句塊中代碼將會被忽略,但不管是否有異常,最后最會執(zhí)行finally子句。
try后面必須接著一個catch或者finally,也就是說JavaScript中的try-catch可以有3中組合形式。即try-catch、try-finally、try-catch-finally三種形式。
try-catch一般的應(yīng)用場景大家都比較熟悉,下面來看幾個嵌套的例子:
上面這個例子中,最外部的try語句塊中嵌套了一個try-finally語句,內(nèi)部的try語句中拋出了一個異常,但是內(nèi)部沒有catch語句塊,所以會執(zhí)行最近的一個catch語句塊。
但是在跳出外部try包含語句塊之前,需要先執(zhí)行內(nèi)部的finally語句塊中的代碼,所以最后的結(jié)果如上圖所示。再看一個例子:
這個例子中,內(nèi)部嵌套的語句塊中有catch語句,所以當(dāng)內(nèi)部try語句塊中拋出異常時,會接著執(zhí)行內(nèi)部的catch語句塊,然后執(zhí)行finally子句。由于異常已經(jīng)在內(nèi)部處理完成,所以外部的catch語句塊會被忽略,所以最終結(jié)果如上所示。再看一個例子:
這個例子在上面例子的基礎(chǔ)上,內(nèi)部的catch語句塊中又拋出了一個異常,所以,在執(zhí)行完相應(yīng)語句后,會接著執(zhí)行外部的catch語句,結(jié)果如上所示。
二, 拋出錯誤
與try-catch語句相配的還有一個throw操作符,用于隨時拋出自定義錯誤。拋出錯誤時,必須要給throw操作符指定一個值。這個值是什么類型,沒有要求。下列代碼都是有效的。throw 12345;
throw 'Hello world!';
throw true;
throw { name: 'JavaScript'};
在遇到throw操作符時,代碼會立即停止執(zhí)行。僅當(dāng)有try-catch語句捕獲到被拋出的值時,代碼才會繼續(xù)執(zhí)行。
通過使用某種內(nèi)置錯誤類型,可以更真實(shí)地模擬瀏覽器錯誤。每種錯誤類型的構(gòu)造函數(shù)接受一個參數(shù),即實(shí)際的錯誤信息。
下面是一個例子:throw new Error('Something bad happened.');
這行代碼拋出了一個通用錯誤,帶有一條自定義錯誤信息。瀏覽器會像處理自己生成的錯誤一樣,來處理這行代碼拋出的錯誤。換句話說,瀏覽器會以常規(guī)方式報告這一錯誤,并且會顯示這里的自定義錯誤類型。像下面使用其他錯誤類型,也可以模擬出類似的瀏覽器錯誤:throw new SyntaxError("I don't like your syntax.");
throw new TypeError("what type of variable do you take me for?");
throw new RangeError("Sorry, you just don't have the range.");
throw new EvalError("That doesn't evaluate.");
throw new URIError("Uri, is that you?");
throw new ReferenceError("You didn't cite your references properly.");
在創(chuàng)建自定義錯誤消息時,最常用的錯誤類型是Error、RangeError、ReferenceError和TypeError。另外,利用原型鏈還可以通過繼承Error來創(chuàng)建自定義錯誤類型。此時,需要為新創(chuàng)建的錯誤類型指定name和message屬性。
來看一個例子:
瀏覽器對待繼承自Error的自定義錯誤類型,就像對待其他錯誤類型一樣。如果要捕獲自己拋出的錯誤并且把它與瀏覽器錯誤區(qū)別對待的話,創(chuàng)建自定義錯誤是很有用的。
IE只有在拋出Error對象的時候才會顯示自定義錯誤信息。對于其他類型,它都無一例外地顯示"exception thrown and not caught"(拋出了異常,且未被捕獲)
總結(jié)
以上是生活随笔為你收集整理的html 中如何写js代码提示错误,javascript怎么进行错误处理?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html中加session,Html中如
- 下一篇: android 日历下面备注,怎样在日历