在执行JavaScript代码的时候,有些状况下会发生错误。html
错误分两种,一种是程序写的逻辑不对,致使代码执行异常。例如:jquery
var s = null; var len = s.length; // TypeError:null变量没有length属性
对于这种错误,要修复程序。网络
一种是执行过程当中,程序可能遇到没法预测的异常状况而报错,例如,网络链接中断,读取不存在的文件,没有操做权限等。函数
对于这种错误,咱们须要处理它,并可能须要给用户反馈。spa
错误处理是程序设计时必需要考虑的问题。对于C这样贴近系统底层的语言,错误是经过错误码返回的:设计
int fd = open("/path/to/file", O_RDONLY); if (fd == -1) { printf("Error when open file!"); } else { // TODO }
经过错误码返回错误,就须要约定什么是正确的返回值,什么是错误的返回值。上面的open()
函数约定返回-1
表示错误。code
显然,这种用错误码表示错误在编写程序时十分不便。htm
所以,高级语言一般都提供了更抽象的错误处理逻辑try ... catch ... finally,JavaScript也不例外。对象
使用try ... catch ... finally处理错误时,咱们编写的代码以下:blog
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>jQuery</title> <script src="/static/js/jquery-3.2.1.min.js"></script> </head> <body> <script> 'use strict'; var r1, r2, s = null; try { r1 = s.length; r2 = 100; } catch (e) { alert('Errors:' + e); } finally { console.log('finally'); } console.log('r1 === ' + r1); console.log('r2 === ' + r2); </script> </body> </html>
运行后能够发现,弹出的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 { ... }
代码。最后请注意,catch
和finally
能够没必要都出现。也就是说,try
语句一共有三种形式:
完整的try ... catch ... finally:
try { ... } catch (e) { ... } finally { ... }
只有try ... catch,没有finally:
try { ... } catch (e) { ... }
只有try ... finally,没有catch:
try { ... } finally { ... }
JavaScript有一个标准的Error
对象表示错误,还有从Error
派生的TypeError
、ReferenceError
等错误对象。咱们在处理错误时,能够经过catch(e)
捕获的变量e
访问错误对象:
try { ... } catch (e) { if (e instanceof TypeError) { alert('Type error!'); } else if (e instanceof Error) { alert(e.message); } else { alert('Error: ' + e); } }
使用变量e
是一个习惯用法,也能够以其余变量名命名,如catch(ex)
。
程序也能够主动抛出一个错误,让执行流程直接跳转到catch
块。抛出错误使用throw
语句。
例如,下面的代码让用户输入一个数字,程序接收到的其实是一个字符串,而后用parseInt()
转换为整数。当用户输入不合法的时候,咱们就抛出错误:
'use strict'; var r, n, s; try { s = prompt('请输入一个数字'); n = parseInt(s); if (isNaN(n)) { throw new Error('输入错误'); } // 计算平方: r = n * n; alert(n + ' * ' + n + ' = ' + r); } catch (e) { alert('出错了:' + e); }
实际上,JavaScript容许抛出任意对象,包括数字、字符串。可是,最好仍是抛出一个Error对象。
最后,当咱们用catch捕获错误时,必定要编写错误处理语句:
var n = 0, s; try { n = s.length; } catch (e) { console.log(e); } console.log(n);
哪怕仅仅把错误打印出来,也不要什么也不干:
var n = 0, s; try { n = s.length; } catch (e) { } console.log(n);
由于catch到错误却什么都不执行,就不知道程序执行过程当中到底有没有发生错误。
处理错误时,请不要简单粗暴地用alert()
把错误显示给用户。教程的代码使用alert()
是为了便于演示。