- 错误分两种,一种是程序写的逻辑不对,导致代码执行异常。例如:
- 一种是执行过程中,程序可能遇到无法预测的异常情况而报错,例如,网络连接中断,读取不存在的文件,没有操作权限等。
var r1, r2, s = null;
try {
r1 = s.length; // 此处应产生错误
r2 = 100; // 该语句不会执行
} catch (e) {
console.log('出错了:' + e);
} finally {
console.log('finally');
}
console.log('r1 = ' + r1); // r1应为undefined
console.log('r2 = ' + r2); // r2应为undefined
错误类型
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);
}
}
抛出错误
程序也可以主动抛出一个错误,让执行流程直接跳转到catch块。抛出错误使用throw语句。
var r, n, s;
try {
s = prompt('请输入一个数字');
n = parseInt(s);
if (isNaN(n)) {
throw new Error('输入错误');
}
// 计算平方:
r = n * n;
console.log(n + ' * ' + n + ' = ' + r);
} catch (e) {
console.log('出错了:' + e);
}
错误传播
如果在一个函数内部发生了错误,它自身没有捕获,错误就会被抛到外层调用函数,如果外层函数也没有捕获,该错误会一直沿着函数调用链向上抛出,直到被JavaScript引擎捕获,代码终止执行。
function main(s) {
console.log('BEGIN main()');
try {
foo(s);
} catch (e) {
console.log('出错了:' + 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);
当bar()函数传入参数null时,代码会报错,错误会向上抛给调用方foo()函数,foo()函数没有try ... catch语句,所以错误继续向上抛给调用方main()函数,main()函数有try ... catch语句,所以错误最终在main()函数被处理了