JavaScript的错误处理
2017-04-17 19:55 by 阿诚de窝, 29 阅读, 0 评论, 收藏, 编辑
错误相关的调试和处理在开发中是特别重要的一种技能。
try-catch
我们来看下面的情况:
1 // noneFunc 这个方法并不存在
2 window.noneFunc();
3 // js 报错后终止运行这行代码并不会执行到
4 console.log("hello");
为了避免不继续执行后续代码的情况,可以对可能抛出错误的代码使用try-catch命令包围。
1 try {
2 // noneFunc 这个方法并不存在
3 window.noneFunc();
4 } catch (error) {
5 // 一旦报错将会跳到这里执行
6 console.log(error.message); // window.noneFunc is not a function
7 }
8 // 执行不中断,这句代码会得到执行
9 console.log("hello");
这里要注意error对象有多个属性,但是message属性是所有浏览器都支持的属性。
finally
在try-catch语句中,finally语句是可选语句,其作用是无论被try-catch包含的代码是否出现错误,都一定会执行finally语句包含的代码,如下:
1 try {
2 window.test();
3 } catch (error) {
4 console.log(error.message);
5 } finally {
6 console.log("finally code");
7 }
8
9 //window.test is not a function
10 //finally code
我们再看一下下面的代码:
1 function test1() {
2 try {
3 return 0;
4 } catch (error) {
5 return 1;
6 } finally {
7 return 2;
8 }
9 }
10
11 console.log(test1()); // 2
12
13 function test2() {
14 try {
15 return 0;
16 } catch (error) {
17 return 1;
18 }
19 }
20
21 console.log(test2()); // 0
22
23 function test3() {
24 try {
25 // test 方法并不存在
26 test();
27 return 0;
28 } catch (error) {
29 return 1;
30 } finally {
31 return 2;
32 }
33 }
34
35 console.log(test3()); // 2
36
37 function test4() {
38 try {
39 // test 方法并不存在
40 test();
41 return 0;
42 } catch (error) {
43 return 1;
44 }
45 }
46
47 console.log(test4()); // 1
从上面的例子来看,在try-catch中包含的return语句都没有执行返回,只会执行finally里的return语句,再看下面的例子:
1 function test() {
2 try {
3 return 0;
4 } catch (error) {
5 return 1;
6 } finally {
7 console.log("finally");
8 }
9 }
10
11 console.log(test()); // 0
如果finally中没有包含return语句,则先执行finally中的语句之后,在返回try-catch语句中的值,我们再看下面的例子:
1 function test1() {
2 var i = 0;
3 try {
4 return ++i;
5 } catch (error) {
6 return -1;
7 } finally {
8 return i;
9 }
10 }
11
12 console.log(test1()); // 1
13
14 function test2() {
15 var i = 0;
16 try {
17 return i++;
18 } catch (error) {
19 return -1;
20 } finally {
21 return i;
22 }
23 }
24
25 console.log(test2()); // 1
我们发现尽管没有执行try-catch中的return语句,但是try-catch中的return语句仍然是执行了的,可以理解为如果finally中存在return关键字,则try-catch中的return关键字都被移除。
还有一种情况,如下:
1 function test1() {
2 var i = 0;
3 try {
4 return 0;
5 } catch (error) {
6 return 1;
7 } finally {
8 if (i != 0) {
9 return 2;
10 }
11 }
12 }
13
14 console.log(test1()); // 0
15
16 function test2() {
17 var i = 0;
18 try {
19 return 0;
20 } catch (error) {
21 return 1;
22 } finally {
23 if (i == 0) {
24 return 2;
25 }
26 }
27 }
28
29 console.log(test2()); // 2
我们还发现,如果由于条件判断等原因,导致finally中的return语句没有执行到,还是会返回try-catch中的return语句。
错误处理
在JavaScript中,有7种内置的错误类型:
- Error:其它6个错误类型的基类,也提供给开发人员自己定义新的错误类型。
- EvalError:执行eval()方法时的报错。
- RangeError:数值超出范围是报错,如:new Array(-20)或new Array(Number.MAX_VALUE)。
- ReferenceError:找不到对象时的报错。
- SyntaxError:执行eval()方法语法错误时报错。
- TypeError:类型错误时的报错,如:new 10或"name" in true时。
- URIError:在调用encodeURI和decodeURI时出错的报错。
对浏览器来说,只要try-catch包含的代码抛出错误,则浏览器认为该错误已经被处理了,我们需要自行处理该错误。
抛出错误
抛出错误使用throw关键字,对于抛出的错误类型则没有规定,可以是任意类型,而浏览器对用户抛出的错误处理也和内置的错误一致,如果没有try-catch进行包含的话,浏览器会暂停JS的执行。
我们可以简单的抛出一个错误类型或自定义类型:
1 throw {msg:"my error"};
2 throw new Error("our error");
我们可以继承Error类型,实现自己的错误类型:
1 function MyError(msg, code) {
2 this.message = msg;
3 this.code = code;
4 }
5
6 MyError.prototype = new Error();
7
8 try {
9 throw new MyError("my error", 1001);
10 } catch (error) {
11 console.log(error.message + ", " + error.code); // my error, 1001
12 }
当然,建议对catch中的error对象使用instanceof关键字进行类型筛选再来有针对性的处理错误。
error事件
error事件仅支持DOM0级的监听方法,即不能通过addEventListener和removeEventListener方法来注册和移除,同时该方法也不会创建对应的event对象,而是将报错信息直接传递过来。
可以理解error事件为整个页面的try-catch语句,如下:
1 window.onerror = function (message, url, line) {
2 console.log("message: " + message + ", url: " + url + ", line: " + line);
3 // 返回 true 则浏览器不会打印错误信息到 console 控制台,返回 false 则浏览器会打印错误信息
4 return true;
5 };
6
7 test();
8
9 // 无论如何报错后的代码都不会再执行了
10 console.log("run this code!");
该事件可以用来在应用开发时收集浏览器中没有被try-catch包围的语句抛出的错误,但实际上在发布给用户的程序中,是不应该存在这样的错误,因为error事件一旦抛出就表示JS代码执行停止了。


浙公网安备 33010602011771号