- 錯(cuò)誤分兩種秃流,一種是程序?qū)懙倪壿嫴粚?duì)赂蕴,導(dǎo)致代碼執(zhí)行異常。例如:
- 一種是執(zhí)行過(guò)程中剔应,程序可能遇到無(wú)法預(yù)測(cè)的異常情況而報(bào)錯(cuò)睡腿,例如,網(wǎng)絡(luò)連接中斷峻贮,讀取不存在的文件席怪,沒(méi)有操作權(quán)限等。
var r1, r2, s = null;
try {
r1 = s.length; // 此處應(yīng)產(chǎn)生錯(cuò)誤
r2 = 100; // 該語(yǔ)句不會(huì)執(zhí)行
} catch (e) {
console.log('出錯(cuò)了:' + e);
} finally {
console.log('finally');
}
console.log('r1 = ' + r1); // r1應(yīng)為undefined
console.log('r2 = ' + r2); // r2應(yīng)為undefined
錯(cuò)誤類(lèi)型
JavaScript有一個(gè)標(biāo)準(zhǔn)的Error對(duì)象表示錯(cuò)誤纤控,還有從Error派生的TypeError挂捻、ReferenceError等錯(cuò)誤對(duì)象。我們?cè)谔幚礤e(cuò)誤時(shí)船万,可以通過(guò)catch(e)捕獲的變量e訪(fǎng)問(wèn)錯(cuò)誤對(duì)象:
try {
...
} catch (e) {
if (e instanceof TypeError) {
alert('Type error!');
} else if (e instanceof Error) {
alert(e.message);
} else {
alert('Error: ' + e);
}
}
拋出錯(cuò)誤
程序也可以主動(dòng)拋出一個(gè)錯(cuò)誤刻撒,讓執(zhí)行流程直接跳轉(zhuǎn)到catch塊。拋出錯(cuò)誤使用throw語(yǔ)句耿导。
var r, n, s;
try {
s = prompt('請(qǐng)輸入一個(gè)數(shù)字');
n = parseInt(s);
if (isNaN(n)) {
throw new Error('輸入錯(cuò)誤');
}
// 計(jì)算平方:
r = n * n;
console.log(n + ' * ' + n + ' = ' + r);
} catch (e) {
console.log('出錯(cuò)了:' + e);
}
錯(cuò)誤傳播
如果在一個(gè)函數(shù)內(nèi)部發(fā)生了錯(cuò)誤声怔,它自身沒(méi)有捕獲,錯(cuò)誤就會(huì)被拋到外層調(diào)用函數(shù)舱呻,如果外層函數(shù)也沒(méi)有捕獲醋火,該錯(cuò)誤會(huì)一直沿著函數(shù)調(diào)用鏈向上拋出悠汽,直到被JavaScript引擎捕獲,代碼終止執(zhí)行芥驳。
function main(s) {
console.log('BEGIN main()');
try {
foo(s);
} catch (e) {
console.log('出錯(cuò)了:' + e);
}
console.log('END main()');
}
function foo(s) {
console.log('BEGIN foo()');
bar(s);
console.log('END foo()');
}
function bar(s) {
console.log('BEGIN bar()');
console.log('length = ' + s.length);
console.log('END bar()');
}
main(null);
當(dāng)bar()函數(shù)傳入?yún)?shù)null時(shí)柿冲,代碼會(huì)報(bào)錯(cuò),錯(cuò)誤會(huì)向上拋給調(diào)用方foo()函數(shù)兆旬,foo()函數(shù)沒(méi)有try ... catch語(yǔ)句假抄,所以錯(cuò)誤繼續(xù)向上拋給調(diào)用方main()函數(shù),main()函數(shù)有try ... catch語(yǔ)句丽猬,所以錯(cuò)誤最終在main()函數(shù)被處理了