52、JavaScript 错误处理

在执行JavaScript代码的时候,有些情况下会发生错误。

 

错误分两种,一种是程序写的逻辑不对,导致代码执行异常。例如:

  1. var s = null;
  2. var len = s.length; // TypeError:null变量没有length属性

 

对于这种错误,要修复程序。

一种是执行过程中,程序可能遇到无法预测的异常情况而报错,例如,网络连接中断,读取不存在的文件,没有操作权限等。

 

对于这种错误,我们需要处理它,并可能需要给用户反馈。

错误处理是程序设计时必须要考虑的问题。对于C这样贴近系统底层的语言,错误是通过错误码返回的:

  1. int fd = open("/path/to/file", O_RDONLY);
  2. if (fd == -1) {
  3. printf("Error when open file!");
  4. else {
  5. // TODO
  6. }

 

通过错误码返回错误,就需要约定什么是正确的返回值,什么是错误的返回值。上面的open()函数约定返回-1表示错误。

显然,这种用错误码表示错误在编写程序时十分不便。

 

因此,高级语言通常都提供了更抽象的错误处理逻辑try ... catch ... finally,JavaScript也不例外。

try ... catch ... finally

 

使用try ... catch ... finally处理错误时,我们编写的代码如下:

  1. 'use strict';
  2. var r1, r2, s = null;
  3. try {
  4. r1 = s.length; // 此处应产生错误
  5. r2 = 100; // 该语句不会执行
  6. catch (e) {
  7. alert('出错了:' + e);
  8. finally {
  9. console.log('finally');
  10. }
  11. console.log('r1 = ' + r1); // r1应为undefined
  12. console.log('r2 = ' + r2); // r2应为undefined
  13. // 直接运行

运行后可以发现,弹出的Alert提示类似“出错了:TypeError: Cannot read property 'length' of null”。

 

我们来分析一下使用try ... catch ... finally的执行流程。

当代码块被try { ... }包裹的时候,就表示这部分代码执行过程中可能会发生错误,一旦发生错误,就不再继续执行后续代码,转而跳到catch块。catch (e) { ... }包裹的代码就是错误处理代码,变量e表示捕获到的错误。最后,无论有没有错误,finally一定会被执行。

 

所以,有错误发生时,执行流程像这样:

先执行try { ... }的代码;

执行到出错的语句时,后续语句不再继续执行,转而执行catch (e) { ... }代码;

最后执行finally { ... }代码。

 

而没有错误发生时,执行流程像这样:

先执行try { ... }的代码;

因为没有出错,catch (e) { ... }代码不会被执行;

最后执行finally { ... }代码。

 

最后请注意,catchfinally可以不必都出现。也就是说,try语句一共有三种形式:

 

完整的try ... catch ... finally

try {

...

} catch (e) {

...

} finally {

...

}

 

只有try ... catch,没有finally

try {

...

} catch (e) {

...

}

 

只有try ... finally,没有catch

try {

...

} finally {

...

}

 

错误类型

JavaScript有一个标准的Error对象表示错误,还有从Error派生的TypeErrorReferenceError等错误对象。我们在处理错误时,可以通过catch(e)捕获的变量e访问错误对象:

  1. try {
  2. ...
  3. catch (e) {
  4. if (e instanceof TypeError) {
  5. alert('Type error!');
  6. else if (e instanceof Error) {
  7. alert(e.message);
  8. else {
  9. alert('Error: ' + e);
  10. }
  11. }

使用变量e是一个习惯用法,也可以以其他变量名命名,如catch(ex)。

 

抛出错误

程序也可以主动抛出一个错误,让执行流程直接跳转到catch块。抛出错误使用throw语句。

 

例如,下面的代码让用户输入一个数字,程序接收到的实际上是一个字符串,然后用parseInt()转换为整数。当用户输入不合法的时候,我们就抛出错误:

  1. 'use strict';
  2. var r, n, s;
  3. try {
  4. s = prompt('请输入一个数字');
  5. n = parseInt(s);
  6. if (isNaN(n)) {
  7. throw new Error('输入错误');
  8. }
  9. // 计算平方:
  10. r = n * n;
  11. alert(n + ' * ' + n + ' = ' + r);
  12. catch (e) {
  13. alert('出错了:' + e);
  14. }

 

实际上,JavaScript允许抛出任意对象,包括数字、字符串。但是,最好还是抛出一个Error对象。

 

最后,当我们用catch捕获错误时,一定要编写错误处理语句:

  1. var n = 0, s;
  2. try {
  3. n = s.length;
  4. catch (e) {
  5. console.log(e);
  6. }
  7. console.log(n);

 

哪怕仅仅把错误打印出来,也不要什么也不干:

  1. var n = 0, s;
  2. try {
  3. n = s.length;
  4. catch (e) {
  5. }
  6. console.log(n);

因为catch到错误却什么都不执行,就不知道程序执行过程中到底有没有发生错误。

 

处理错误时,请不要简单粗暴地用alert()把错误显示给用户。教程的代码使用alert()是为了便于演示。

 

JavaScript 错误处理

付杰
wordpress站群服务 泛解析二级域名 二级目录
wordpress站群服务 泛解析二级域名 二级目录
  • ¥ 1999.9元
  • 市场价:8999元
SEO顾问 单站最低999元 整站全方位优化
SEO顾问 单站最低999元 整站全方位优化
  • ¥ 999元
  • 市场价:4999元
刷流量 刷人气 刷点击 刷收藏 刷APP关键词
刷流量 刷人气 刷点击 刷收藏 刷APP关键词
  • ¥ 1.0元
  • 市场价:9.9元
Microsoft 全家桶 “激活码/产品密钥”永久
Microsoft 全家桶 “激活码/产品密钥”永久
  • ¥ 29.99元
  • 市场价:888元

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: