错误处理
当 JavaScript 引擎执行 JavaScript 代码时,会发生各种错误:
可能是语法错误,通常是程序员造成的编码错误或错别字。
可能是拼写错误或语言中缺少的功能(可能由于浏览器差异)。
可能是由于来自服务器或用户的错误输出而导致的错误。
当然,也可能是由于许多其他不可预知的因素。
JavaScript 抛出错误
当错误发生时,当事情出问题时,JavaScript 引擎通常会停止,并生成一个错误消息。
描述这种情况的技术术语是:JavaScript 将抛出一个错误。
测试和捕捉
try
语句允许我们定义在执行时进行错误测试的代码块。
catch
语句允许我们定义当 try
代码块发生错误时,所执行的代码块。
JavaScript 语句 try
和 catch
是成对出现的。
try{
// 可能出错需要捕获异常的代码
}catch(err){
// 异常处理代码
}
比如,我们故意引用未定义的变量,使得 JavaScript 抛出异常:
try{
console.log(x) // x 未定义
}catch(err){
console.log(err)
}
throw 语句
错误除了可以使系统抛出的以外,还可以是我们自己定义的。
throw 语句允许我们创建自定义错误。正确的技术术语是:抛出异常(exception)。
如果把 throw 与 try 和 catch 一起使用,那么您能够控制程序流,并生成自定义的错误消息。
try{
throw "a test err"
}catch(err){
console.log(err)
}
可以看出,我们可以抛出任意类型的对象;catch
中接受的参数即为我们抛出的对象。
很多时候我们需要获得更多出错信息,比如系统给我们抛出的异常就有堆栈信息。
try{
console.log(x) // x 未定义
}catch(err){
console.log(err)
}
自定义错误如何或者更多的出错信息那?这时候我们可以采用 Error
来构造对象。
try{
throw new Error("a error with more info")
}catch(err){
console.log(err)
}
Error 类型
执行代码期间可能会发生的错误有多种类型。每种错误都有对应的错误类型,而当错误发生时,就会抛出相应类型的错误对象。ECMA-262定义了下列7种错误类型:
- Error
- EvalError(eval错误)
- RangeError(范围错误)
- ReferenceError(引用错误)
- SyntaxError(语法错误)
- TypeError(类型错误)
- URIError(URI错误)
其中,Error是基类型,其他错误类型都继承自该类型。因此,所有错误类型共享了一组相同的属性。Error类型的错误很少见,如果有也是浏览器抛出的;这个基类型的主要目的是供开发人员抛出自定义错误
finally 子句
ECMA-262第3版引入了try-catch语句,作为javascript中处理异常的一种标准方式,用于捕获和处理错误
其中,try从句定义了需要处理的异常所在的代码块。catch从句跟随在try从句之后,当try块内某处发生了异常时,调用catch内的代码逻辑。catch从句后跟随finally块,后者中放置清理代码,不管try块中是否产生异常,finally块内的逻辑总是会执行。尽管catch和finally都是可选的,但try从句需要至少二者之一与之组成完整的语句
try/catch/finally语句块都需要使用花括号括起来,这里的花括号是必需的,即使从句中只有一条语句也不能省略花括号
try{
//通常来讲,这里的代码会从头到尾而不会产生任何问题
//但有时会抛出一个异常,要么是由throw语句直接抛出,要么通过调用一个方法间接抛出
}catch(e){
//当且仅当try语句块抛出了异常,才会执行这里的代码
//这里可以通过局部变量e来获得对Error对象或者抛出的其他值的引用
//这里的代码块可以基于某种原因处理这个异常,也可以忽略这个异常,还可以通过throw语句重新抛出异常
}finally{
//不管try语句是否抛出了异常,finally里的逻辑总是会执行,终止try语句块的方式有:
//1、正常终止,执行完语句块的最后一条语句
//2、通过break、continue或return语句终止
//3、抛出一个异常,异常被catch从句捕获
//4、抛出一个异常,异常未被捕获,继续向上传播
}