一、语法
try...catch
可以测试代码中的错误。try
部分包含需要运行的代码,而 catch
部分包含错误发生时运行的代码。
try
语句允许定义在执行时进行错误测试的代码块。catch
语句允许定义当try
代码块发生错误时,所执行的代码块。finally
语句在try
和catch
之后无论有无异常都会执行。
注意点:
catch
和finally
语句都是可选的,但在使用try
语句时必须至少使用一个。当错误发生时, JavaScript 会停止执行,并生成一个错误信息。可以使用throw
语句 来创建自定义消息(抛出异常)
try {
// tryCode - 尝试执行代码块
}
catch(err) {
// catchCode - 捕获错误的代码块
} finally {
// finallyCode - 无论 try / catch 结果如何都会执行的代码块
}
二、捕获异常
在开发中,由于各种问题,异常的出现时不可控的,所以需要对异常进行处理,优化用户体验。
异常处理的场景
- JS 语法错误、代码异常
- Promise 异常
- Iframe 异常
- 跨域异常
- 接口请求AJAX 请求异常
- 静态资源导入加载异常
try catch的注意点: 只能捕获到同步的异常,不能捕获语法和异步的异常,在日常使用中需要注意。
// 不能捕获语法的异常
try {
let name = 'aaa // 少写'
}
catch(e) {
console.log('捕获到异常:',e);
}
// VM421:1 Uncaught SyntaxError: Unexpected identifier
// 不能捕获异步的异常
try {
setTimeout(() => {
console.log(a) // 未声明a变量
}, 1000) }
catch(e) {
console.log('捕获到异常:',e);
}
// blog.js:1 Uncaught ReferenceError: a is not defined
三、应用场景
1.兼容性场合
因为浏览器兼容性不是程序员能改正的,所以只能try catch:由于不同浏览器的报错提示是不一样的,根据捕获的浏览器的报错提示判断用户的浏览器,然后做出对应的措施,这时候使用try catch是巧妙的办法,如果用if就比较笨拙,因为if通常只能反馈真或假,不能直接反馈浏览器的报错内容。
2.写法省心
考虑如下代码。window.a.b
是非法的,再跟2对比就没有意义,这样非法的条件,在try catch
中仍可以继续运行下去。但在if
中window.a.b
已经报错,整个页面都会坏掉。如果希望用if
写,那么必须先判断window.a是否是合法的,window.a是合法的前提下再判断window.a.b是不是合法的,如果也是合法的,再判断window.a.b是否不等于2,这样是不是很蠢?这时就体现出try catch的妙处了,程序不但知道window.a.b !== 2是假的,而且直接可以知道究竟哪一步就已经是假的。
再想象一下,有一个变量是json.a.b.c
,其中的a/b/c都可能是存在的也可能是不存在的,全看具体情况,这时候你简单的写if (json.a.b.c === 2) {...}是不行的,因为json.a.b就可能已经是非法的,所以你如果用if,就要考虑a是不是非法的、a是合法前提下b是不是非法的,b是合法前提下c是不是非法的。但是json.a.b.c === 2在try中就可以直接写,也就是说,我不关心究竟a/b/c谁是非法的,我只关心json.a.b.c到底是不是等于2,不等于2或者任何一步出错,对我来讲没有区别,反正都是不等于2,我不关心哪步出错,而且程序不会坏掉。这是一种比较省心的写法。
try catch不能做真假判断,只能做非法判断。也就是说:try {1 === 2},虽然1===2是假,但是是合法的,catch不会捕捉到错误,也不会告诉你1 === 2到底是真是假。所以,写在try里的应该是json.a.b.c而不是json.a.b.c === 2。究竟是不是等于2,是后面的事,是if干的事。简单说,try catch用于捕捉报错,当你不关心哪一步错误,只关心有没有错,就用try catch
//try_catch好处:发现错误但不让程序终止,继续执行之后的语句
try{
//先从上到下执行try里面的语句,一旦发现错误则跳出try,不再执行try下面的语句
console.log("a");
console.log(b);
console.log("c");
}catch(e){
//如果try中发现错误,则执行catch中的语句,如果没有错误,则跳过catch
//e是个系统封装好的对象,包含name和message两个属性
//分别是错误名称(ex:ReferenceError)和错误信心(ex:b is not defined)
console.log(e.name+":"+e.message);
}
console.log('d');
六种错误类型
- EvalError: eval()的使用与定义不一致
- RangeError: 数值越界
- ReferenceError:非法或者不能识别的引用数值
- SyntaxError: 发生语法解析错误
- TypeError: 操作数类型错误
- URIError: URL处理函数使用不当
四、throw error 与 throw new Error(error)
javascript
中 throw error
与 throw new Error(error)
抛出错误一般都是与try catch
同时出现的
1.定义
throw new Error(error)
; 这个是创建错误,创造一个错误类型抛出\throw error
这个是抛出错误。
eg: throw new Error(error)
let a = 5;
try{
if(a==5){
// 抛出错误
throw new Error("loopTerminates"); //Error要大写
}
}catch(e){
console.log(e); //打印出Error对象:Error: loopTerminates
console.log(e.message); //打印:loopTerminates
}
throw error
var a = 5;
try{
if(a==5){
// 抛出错误
throw "loopTerminates"; // 不建议的写法
}
}catch(e){
console.log(e); //打印: loopTerminates
console.log(e.message); //打印:undefined
}
2.抛出异常/捕获异常举例
抛出异常
//在工作时遇到了需要抛出异常并且需要自己捕获处理的地方,于是在抛出的地方写下
function parseExcel(con) {
try {
// doSomething
} catch (error) {
throw new Error('parse excel failed');
}
}
捕获异常
try {
parseExcel(con);
} catch (error) {
if (error.message === 'parse excel failed') {
//doSomething
}
}