一、什么是例外处理(exception handlers)
当JavaScript程序在运行中发生了诸如数组索引越界、类型不匹配或者语法错误时,JavaScript解释器就会引发例外处理。ECMAScript定义了六种类型的错误,除此之外,我们可以使用Error对象和throw语句来创建并引发自定义的例外处理信息。
二、例外处理技术的优点
通过运用例外处理技术,我们可以实现用结构化的方式来响应错误事件的发生,让例外处理代码与正常脚本代码科学分离,最终使我们能够集中精力编写完成主要功能的核心程序。
三、使用 try…catch…finally 执行例外处理
在JavaScript中,我们使用try…catch…finally语句来执行例外处理,即通过它来捕捉错误发生后导致的例外或者执行throw语句产生的例外。它的基本语法如下:
try {
// 此处是可能产生例外的语句
} catch(error) {
// 此处是负责例外处理的语句,error参数为一个错误对象
} finally {
// 此处是出口语句
}
上述代码中,try块中的语句首先被执行。如果运行中发生了错误,控制就会转移到位于catch块中语句,其中括号中的error参数被作为例外变量传递。否则,catch块的语句被跳过不执行。无论是发生错误时catch块中的语句执行完毕,或者没有发生错误try块中的语句执行完毕,最后将执行finally块中的语句。
try {
console.log("开始执行try块语句 ---> ")
console.log("还没有发生例外 ---> ")
eval((prompt("输入一段JS代码:","")))
} catch(err) {
console.log("捕捉到例外,开始执行catch块语句 --->");
console.log("错误名称: " + err.name+" ---> ");
console.log("错误信息: " + err.message+" ---> ");
} finally {
console.log("开始执行finally块语句")
}
在浏览器中运行上面的代码过程如下:
- 控制台输出:开始执行try块语句 --->
- 控制台输出:还没有发生例外 --->
- 浏览器弹出prompt框
- 如果输入可正确执行的JS代码,接7
- 如果输入错误代码,接4
- 控制台输出:捕捉到例外,开始执行catch块语句 --->
- 控制台输出:错误名称: ReferenceError --->
- 控制台输出:错误信息: 'xxx' is not defined --->
- 控制台输出:开始执行finally块语句
上述例程以try块语句开始,当输出信息“还没有发生例外”后,弹出输入对话框,当输入"xxx"后,就引发了一个例外,所以剩下的try块中的语句将被跳过而开始执行catch块语句。Catch块开始的err参数作为这个例外的错误对象,它具有name和message两个属性。最后,执行finally块的语句。
如果在输入框当输入"1 == 1",由于没有错误发生,当try块的语句执行完毕后,catch块语句被跳过,直接执行finally块的语句。
四、try...catch...finally变体
try…catch…finally语句可以省略finally部分,即try…catch。
try…catch结构执行过程是try块中的语句首先被执行。如果运行中发生了错误,控制就会转移到位于catch块中语句,其中括号中的error参数被作为例外变量传递。否则,catch块的语句被跳过不执行。
五、Error对象
在JavaScript,例外是作为Error对象出现的。Error对象有两个属性:name属性表示例外的类型,message属性表示例外的含义。Error.name的取值一共有六种,如下:
- Error:()的使用与定义不一致
- RangeError:数值越界
- ReferenceError:非法或不能识别的引用数值
- SyntaxError:发生语法解析错误
- TypeError:操作数类型错误
- URIError:URI处理函数使用不当
六、自定义error对象
上述的六种Error类型基本上覆盖了脚本程序运行时所可能发生的错误。除了这些类型以外,我们还可以使用Error构造器来自定义例外类型,其语法如下:
var myError = new Error('this is an error')
myError.name = "MyError"
使用构造函数创建error对象
function MyError(msg) {
this.name = "MyError"
this.message = msg
}
MyError.prototype = new Error
var myError = new MyError('this is an error')
七、throw 触发例外
创建一个Error对象后,可以使用throw语句来触发的例外。Throw用法如下:
var s = 0
var myError = new Error("throw error")
try {
s ++
throw myError //throw的目标必须是一个Error对象
//在try块代码中throw一个Error对象,将直接转入catch
s ++ //这行代码将不会执行
} catch(err) {
console.log(err.message)
}
console.log(s) // 在控制台输出 1
使用throw配合自定义Error对象,可以快速转入catch块执行,并将错误传递到外层(见下文嵌套例外)。
八、嵌套例外处理
JavaScript支持多层嵌套例外处理。一般情况下,我们可以在内部例外处理的catch代码块中捕捉并处理错误,然后再次触发例外,这样就可进一步在外部例外处理的catch代码块中做更加深入的处理。下面来看看一个嵌套例外处理的例子:
try {
console.log("外层try代码块 start");
try{
console.log("内层try代码块 start");
throw new Error('throwInnerError');// 抛出一个自定义错误,直接转到内层catch代码块
console.log("内层try代码块 end"); //这里将不会执行
} catch(innerError) {
console.log("内层catch代码块 start");
console.log("输出innerError信息: " + innerError.message);
throw innerError;// 抛出try中定义的错误,触发外层catch代码块
console.log("内层catch代码块 end"); //这里将不会执行
} finally {
console.log("内层finally代码块");
}
console.log("外层try代码块 end");//这里将不会执行
} catch(outerError) {
console.log("外层catch代码块 start");
console.log("输出outerError信息: " + outerError.message);
console.log("外层catch代码块 end");
} finally {
console.log("外层finally代码块");
}
执行后的输出结果如下:
- 外层try代码块 start
- 内层try代码块 start
- 内层catch代码块 start
- 输出innerError信息: throwInnerError
- 内层finally代码块
- 外层catch代码块 start
- 输出outerError信息: throwInnerError
- 外层catch代码块 end
- 外层finally代码块
嵌套例外处理的好处在于使我们能够很好地分阶段处理错误,内部例外处理可以负责解决由错误引发的脚本代码问题,外部例外处理则用于负责提供给用户的反馈信息或者对例外信息进行日志记录。
原文地址:https://www.cnblogs.com/luluping/archive/2011/02/14/1954092.html