错误处理在处理程序设计中的重要性是毋庸置疑的,任何有影响力的web应用程序都需要一套完善的错误处理机制。

1. try-catch 语句

引言:

ECMA-262第3版引入了try-catch语句,作为JavaScript中处理异常的一种标准方式。基本的语法如下所示,显而易见,这与Java中的try-catch语句是完全相同的:

示例:
try {
    //可能会导致错误的代码
} catch (error) {
    //在错误发生时怎么处理
}

也就是说,我们应该把所有可能会抛出错误的代码都放在try语句快中,而把那些用于错误处理的代码放在catch块中,例如:

try {
    window.someNonexistentFunction(); //调用不存在的函数
} catch (error) {
    alert('An error happened!');
}
注意:

如果try块中的任何代码发生了错误,就会立即退出代码执行过程,然后接着执行catch块,此时,catch块会接收到一个包含错误信息的对象。与在其他语言中不同的是,即使你不想使用这个错误对象,也要给它起个名字。这个对象中包含的实际信息会因浏览器而异,但共同的是有一个保存着错误信息的message属性。ECMA-262还规定了一个保存着错误类型的name属性,当前所有浏览器都支持这个属性(Opera9之前的版本不支持这个属性)。因此,在发生错误时,就可以像下面这样实事求是地显示浏览器给出的信息:

try {
    window.someNonexistentFunction(); //调用不存在的函数
} catch (error) {
    alert(error.message);
}

这个例子在向用户显示错误信息时,使用了错误对象的message属性,这个message属性是唯一一个能保证所有浏览器都支持的属性,除此之外,IE、Firefox、Safari、Chrome以及Opera都为事件对象添加了其他相关信息。IE添加了与message属性完全相同的description属性,还添加了保存着内部错误数量的number属性。Firefox添加了fileName、lineNumber和stack(包含栈跟踪信息)属性。Safari添加了line(表示行号)、sourceId(表示内部错误代码)和sourceUrl属性。当然,在跨浏览器编程时,最好还是只使用message属性

2. finally子句

引言:

虽然在try-catch语句中是可选的,但finally子句一经使用,其代码无论如何都会执行。 换句话说,try语句块中的代码全部正常执行,finally子句会执行;如果因为出错而执行了catch语句块,finally子句照样还会执行。只要代码中包含finally子句,则无论try或catch语句块中包含什么样的代码——甚至return语句,都不会阻止finally子句的执行。 来看下面这个函数:

function testFinally() {
    try {
        return 2;
    } catch (error) {
        return 1;
    } finally {
        return 0;
    }
}

testFinally(); //0

这个函数在try-catch语句的每一部分都放了一条return语句。表面上看,调用这个函数会返回2,因为返回2个return语句位于try语句块中,而执行该语句又不会出错。可是,由于最后还有一个finally子句,结果就会导致该return语句被忽略,也就是说,调用这个函数只能返回0,如果把finally子句拿掉,这个函数将返回2.(请读者务必要记住,只要代码中包含finally子句,那么无论try还是catch语句块中的return语句都将被忽略。因此,在使用finally子句之前,一定要非常清楚你想要代码怎么样)。

3.错误类型

执行代码期间可能会发生的错误有多种类型,每种错误都有对应的错误类型,而当错误发生时,就会抛出相应类型的错误对象。ECMA-262定义了下列7种错误类型:

01, Error
02, EvalError(在使用eval()函数而发生异常时抛出)
03, RangeError(数值超出相应范围时触发)
04, ReferenceError(在访问不存在的变量时,就会发生这种错误)
05, SyntaxError(语法错误)
06, TypeError(执行特定于类型的操作时,变量的类型并不符合要求所致)
07, URIError(在使用encodeURI()或decodeURI(),而URI格式不正确时,就会导致URIError错误)

其中,Error是基类型,其他错误类型都继承自该类型,因此,所有错误类型共享了一组相同的属性(错误对象中的方法全是默认的对象方法)。Error类型的错误很少见,如果有也是浏览器抛出的;这个基类型的主要目的是供开发人员抛出自定义错误

4. 抛出错误

与try-catch语句相配的还有一个throw操作符,用于随时抛出自定义错误。抛出错误时,必须要给throw操作符指定一个值。这个值是什么类型,没有要求。下列代码都是有效的。

throw 12345;
throw 'Hello world!';
throw true;
throw { name: 'JavaScript'};

在遇到throw操作符时,代码会立即停止执行。仅当有try-catch语句捕获到被抛出的值时,代码才会继续执行。