在執行JavaScript代碼的時候,有些情況下會發生錯誤,錯誤分兩種
一種是程序寫的邏輯不對,導致代碼執行異常
var s = null;
var len = s.length; // TypeError:s is nul
length in null;//TypeError: right-hand side of 'in' should be an object, got null
null沒有length屬性,對於這種錯誤,要修復程序
一種是執行過程中,程序可能遇到無法預測的異常情況而報錯,例如,網絡連接中斷,讀取不存在的文件,沒有操作權限等。對於這種錯誤,我們需要處理它,並可能需要給用戶反饋
錯誤處理是程序設計時必須要考慮的問題,對於C這樣貼近系統底層的語言,錯誤是通過錯誤碼返回的
int fd = open("/path/to/file", O_RDONLY);
if (fd == -1)//-1錯誤碼
{ printf("Error when open file!"); }
通過錯誤碼返回錯誤,就需要約定什麼是正確的返回值,什麼是錯誤的返回值。上面的open()函數約定返回-1表示錯誤
而JavaScript提供了處理錯誤的函數,try … catch … finally
try …catch … finally的執行流程
當代碼塊被try { … }包裹的時候,就表示這部分代碼執行過程中可能會發生錯誤,一旦發生錯誤,就不再繼續執行try部分的後續代碼,轉而跳到catch,catch (e) { … }包裹的代碼就是錯誤處理代碼,變量e表示捕獲到的錯誤。最後無論有沒有錯誤,finally一定會被執行
所以,有錯誤發生時執行流程
- 先執行try { … }的代碼;
- 執行到出錯的語句時,後續語句不再繼續執行,轉而執行catch (e) { … }代碼
- 最後執行finally { … }代碼
而沒有錯誤發生時,執行流程像這樣
- 先執行try { … }的代碼;
- 因爲沒有出錯,catch (e) { … }代碼不會被執行
- 最後執行finally { … }代碼
(提醒一下:使用變量e只是一個習慣用法,也可以用其他變量名命名,如catch(er),這個變量只是代表出現的錯誤,並沒有強制要求變量名)
var r1, r2, s = null;
try {
r1 = s.length; //這個地方出錯了,所以r2賦值不會被執行
r2 = 100; }
catch (e) { alert('出錯了:' + e); }
finally { console.log('finally'); }
console.log('r1 = ' + r1);//r1 = undefined
console.log('r2 = ' + r2);//r2 = undefined
運行後可以發現,彈出的Alert提示“出錯了:TypeError: s is null ”
其實,catch和finally可以不必都出現,也就是說,try語句一共有三種形式
完整的try …catch … finally
只有try …catch,沒有finally:
只有try … finally,沒有catch
JavaScript有一個標準的Error對象表示錯誤,還有從Error派生的TypeError、ReferenceError等錯誤對象
在處理錯誤時,可以通過catch(e)捕獲的變量e訪問錯誤對象
try
{... }
catch (e)
{
if (e instanceof TypeError)
{ alert('Type error!'); }
else if (e instanceof Error)
{ alert(e.message); }
else { alert('Error: ' + e); }
}
TyoeErrir也是Error的一個類
instanceof 是JavaScript中的一個雙目運算符,用來測試一個對象是否爲一個類的實例,用法爲:
boolean result = obj instanceof Class
其中 obj 爲一個對象,Class 表示一個類或者一個接口,當 obj 爲 Class 的對象,或者是其直接或間接子類,或者是其接口的實現類,結果result 都返回 true,否則返回false。
剛纔我也試了一下
var a=TypeError
a instanceof TypeError//false
拋出錯誤
程序也可以主動拋出一個錯誤,讓執行流程直接跳轉到catch塊
拋出錯誤使用throw語句
下面的代碼讓用戶輸入一個數字,程序接收到的實際上是一個字符串,然後用parseInt()轉換爲整數,當用戶輸入不合法的時候,我們就拋出錯誤
對了,剛纔忘記說了,catch(e)
e相當於是Error: 輸入錯誤
e.message是輸入錯誤(具體的內容)
至於是選擇e還是選擇e.message就看你的需要啦
var r, n;
try {
n =parseInt(prompt('請輸入一個數字'));
if (isNaN(n))
{ throw new Error('輸入錯誤'); } //如果是錯誤就直接跳過後面內容,可以通過輸入非數字主動報錯
r = n * n;
alert(n + ' * ' + n + ' = ' + r); }
catch (e)
{ alert('出錯了:' + e.message); }
實際上,JavaScript允許拋出任意對象,包括數字、字符串,但是,最好還是拋出一個Error對象
最後,當我們用catch捕獲錯誤時,一定要編寫錯誤處理語句,因爲可以及時知道程序執行過程中到底有沒有發生錯誤,進而及時debug
所以下面兩種寫法,最好還是給catch裏面加點內容吧
var n = 0, s;
try
{n = s.length; }
catch (e)
{ console.log(e); }
console.log(n);
var n = 0, s;
try {n = s.length; }
catch (e) { }
console.log(n);