js如何处理错误

错误处理

在 Javascript 中,处理异常的方式一般有两种:

  • try-catch 语句捕获异常
  • onerror 事件捕获异常

一、try-catch 语句

try-catch 语句是 Javascript 中处理异常的一种标准方式,基本语法如下:

1
2
3
4
5
try {
// 可能会导致错误的代码
} catch (error) {
// 在错误发生时处理
}

对于 catch 捕获的异常对象 error,在不同浏览器中它包含的信息可能不太一样。一般来说,error 中通用的属性仅包括 message,也就是说,在跨浏览器编写代码时,最好只使用 message 属性。

1
2
3
4
5
6
try {
// 可能会导致错误的代码
} catch (error) {
// 跨浏览器的通用属性仅有 message
alert(error.message);
}

实际上,try-catch 语句还包括了 finally 块,用于表示 finally 块内的语句一定会执行。

无论代码怎么处理,下述代码最后返回的结果始终是 finally 块的 0:

1
2
3
4
5
6
7
8
9
10
try {
// 其他代码
return 1;
} catch (error) {
// 错误处理代码
return -1;
} finally {
// 其他代码
return 0;
}

另外需要注意的是,如果代码中包含了 finally 语句,那么 try 块和 catch 块内的 return 语句都将会被忽略,下述代码返回的既不是 1 也不是 -1,实际返回的是 finally 的代码结果,但是由于 finally 块内没有 return 语句,因此会默认返回 undefined

1
2
3
4
5
6
7
8
9
10
try {
// 其他代码
return 1;
} catch (error) {
// 错误处理代码
return -1;
} finally {
// 其他代码
// 实际上这里会返回 undefined
}

因此在使用 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
2
3
// 这些会抛出异常
new eval();
eval = 1;

1.1.3 RangeError

RangeError 会在数值超出相应范围时触发。比如数组的大小超出了范围:

1
2
3
// 非法范围会抛出异常
var arr1 = new Array(-10);
var arr2 = new Array(Number.MAX_VALUE);

1.1.4 ReferenceError

ReferenceError 会在访问不存在的变量时触发,比如把未声明的变量用来赋值:

1
2
// firstname 未定义时会抛出异常
var name = firstname;

1.1.5 SyntaxError

SyntaxError 一般是因为语法错误引起,比如将语法错误的字符串传进 eval 中执行时:

1
2
// 语法错误异常
eval("a ++ b");

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
2
3
4
throw 123;
throw "123"
throw false;
throw { name: 'zhangsan'}

但是一般来说,抛出 Error 错误类型会更好一些,因为这样会比较方便 catch 处理该异常信息。

1
2
throw new EvalError("eval error!");
throw new TypeError("type error!");

也可以自定义错误,利用原型链继承 Error 来创建自定义的错误类型:

1
2
3
4
5
6
7
8
function CustomError (message) {
this.name = "CustomError";
this.message = message;
}

CustomError.prototype = new Error();

throw new CustomError("custom error!");

二、onerror 事件

任何没有通过 try-catch 语句处理的错误都会触发 window 对象的 error 事件(Opera、Safari 浏览器不支持 error 事件)。

在任何 Web 浏览器中,onerror 事件处理程序都不会创建 event 对象,只会接收3个参数:

  • 错误信息
  • 错误所在的 URL
  • 错误所在行号

只要发生错误,无论是不是浏览器生成的,都会触发 error 事件。

作者

jiaduo

发布于

2021-08-28

更新于

2023-04-02

许可协议