js如何处理错误
错误处理
在 Javascript 中,处理异常的方式一般有两种:
- try-catch 语句捕获异常
- onerror 事件捕获异常
一、try-catch 语句
try-catch 语句是 Javascript 中处理异常的一种标准方式,基本语法如下:
1 | try { |
对于 catch 捕获的异常对象 error,在不同浏览器中它包含的信息可能不太一样。一般来说,error 中通用的属性仅包括 message,也就是说,在跨浏览器编写代码时,最好只使用 message 属性。
1 | try { |
实际上,try-catch 语句还包括了 finally 块,用于表示 finally 块内的语句一定会执行。
无论代码怎么处理,下述代码最后返回的结果始终是 finally 块的 0:
1 | try { |
另外需要注意的是,如果代码中包含了 finally 语句,那么 try 块和 catch 块内的 return 语句都将会被忽略,下述代码返回的既不是 1 也不是 -1,实际返回的是 finally 的代码结果,但是由于 finally 块内没有 return 语句,因此会默认返回 undefined
:
1 | try { |
因此在使用 finally 块时,需要注意它的返回值。
还有一点需要说的就是,IE7 以前的版本有一个 bug,如果没有 catch 语句,finally 也不会执行。因此在写 IE7 以前版本的代码时,使用 finally 语句时必须要先写 catch 语句。
1.1 错误类型
ECMA-262 定义了7种错误类型:
- Error
- EvalError
- RangeError
- ReferenceError
- SyntaxError
- TypeError
- URIError
1.1.1 Error
Error
是基类型,其他错误类型均继承自该类型。
1.1.2 EvalError
EvalError
会在使用 eval()
函数时发生异常而被抛出,比如如果没有把 eval 当作函数来调用:
1 | // 这些会抛出异常 |
1.1.3 RangeError
RangeError
会在数值超出相应范围时触发。比如数组的大小超出了范围:
1 | // 非法范围会抛出异常 |
1.1.4 ReferenceError
ReferenceError
会在访问不存在的变量时触发,比如把未声明的变量用来赋值:
1 | // firstname 未定义时会抛出异常 |
1.1.5 SyntaxError
SyntaxError
一般是因为语法错误引起,比如将语法错误的字符串传进 eval 中执行时:
1 | // 语法错误异常 |
1.1.6 TypeError
TypeError
会在变量中保存着意外的类型,或者在访问不存在的方法时触发。比如传给函数的参数类型与预期的类型不相符:
1 | alert("name" in true); |
1.1.7 URIError
URIError
一般会在使用 encodeURI()
或 decodeURI()
,而 URI 格式不正确时触发。不过这两个方法的容错率比较高,不容易触发这个错误。
1.2 throw 抛出异常
与 try-catch 语句相配的还有一个 throw 操作符,用于抛出自定义错误。
使用 throw 抛出错误时,必须指定一个错误值,但是这个错误值的类型没有要求,可以是任意类型:
1 | throw 123; |
但是一般来说,抛出 Error 错误类型会更好一些,因为这样会比较方便 catch 处理该异常信息。
1 | throw new EvalError("eval error!"); |
也可以自定义错误,利用原型链继承 Error 来创建自定义的错误类型:
1 | function CustomError (message) { |
二、onerror 事件
任何没有通过 try-catch 语句处理的错误都会触发 window 对象的 error 事件(Opera、Safari 浏览器不支持 error 事件)。
在任何 Web 浏览器中,onerror 事件处理程序都不会创建 event 对象,只会接收3个参数:
- 错误信息
- 错误所在的 URL
- 错误所在行号
只要发生错误,无论是不是浏览器生成的,都会触发 error 事件。