-
Notifications
You must be signed in to change notification settings - Fork 111
Description
基础
try {
// 可能会导致错误的代码
} catch (err) {
// 在错误发生时怎么处理
} finally {
// 无论是否报错都会执行
}
try-catch
是针对可能抛出错误代码,避免因报错而中断整体代码的运行。
try
不能单独使用,必须搭配 catch
或 finally
使用。
当 try
代码块内抛出错误时,则从该代码行起后续代码将不会执行(当前代码块),直接进入 catch
。若 try
没有抛出错误,则会跳过 catch
。
当 try
代码块内抛出错误时,但未定义 catch
,即只定义了 finally
,那么仍会中断整体代码的运行。
throw
语句用来抛出一个用户自定义的异常。当前函数的执行将被停止(throw
之后的语句将不会执行),并且控制权将被传递到调用堆栈中的第一个catch
块。如果调用者函数中没有catch
块,程序将会终止。
延伸:return throw new Error() 是错误的语法
Uncaught SyntaxError: Illegal return statement
。MDN 上return [[expression]];
return 后面接的是表达式而不是语句,而 throw 是语句。另外,throw 本身也会中断当前代码块后续代码的运行。
无论是否抛出异常 finally
子句都会执行。即使没有 catch
子句处理异常。
当发生异常时,可以使用 finally
子句使您的脚本以更优雅的方式处理错误的情况。例如,释放已经绑定的资源等。
openMyFile()
try {
// tie up a resource
writeMyFile(theData)
}
finally {
closeMyFile() // always close the resource
}
嵌套
try
可以嵌套,当内部 try
没有对应的 catch
,则抛出的错误被最近且有定义 catch
的上层所捕获。
执行顺序
throw
try {
console.log(1)
throw new Error('err')
} finally {
console.log(2)
}
// 由于未定义 catch,抛出的错误会导致中断整体代码的运行
// 另外,这里的输出是:1 2 Error。至于 finally 为何先于 try 抛出的 Error,目前笔者没有深入考究。
假如以上代码块的 finally
也抛出错误,即如下:
try {
console.log(1)
throw new Error('a')
} finally {
throw new Error('b')
console.log(2)
}
// 那么输出 1 Error('b')。即 finally 里抛出的错误已经导致整体流程的中断(或取代了 Error('a'))。
return
在 try 中加入 return 语句
function test () {
try {
console.log(1);
return 'from_try';
} catch (e) {
// TODO
} finally {
console.log(2);
}
}
console.log(test()); // 1 2 from_try
从以上输出结果可看出,return 与上一小节 throw 情况类似,即 finally
优先于 try
的 throw
和 return
。
在 finally 也加入 return 语句
function test () {
try {
console.log(1)
return 'from_try'
} catch (e) {
// TODO
} finally {
console.log(2)
return 'from_finally'
}
}
console.log(test()); // 1 2 from_finally
同上,与上一小节 throw 情况类似,finally 的 return 优先于(或取代了) try
的 return
(上一小节是 throw)。
在 try 语句里抛出错误
function test () {
try {
console.log(1);
throw new Error('from_try')
} catch (e) {
console.log(e.message)
return 'from_catch'
} finally {
console.log(2)
}
}
console.log(test()) // 1 from_try 2 from_catch
从以上结果可看出,try
和 catch
的 return
都需要先经过 finally
,与 throw
类似。
将 return
改为 throw
进行验证:
function test () {
try {
console.log(1)
throw new Error('from_try')
} catch (e) {
console.log(e.message)
throw new Error('from_catch')
} finally {
console.log(2)
}
}
test() // 1 from_try 2 from_catch
可见,throw
与 return
对代码执行流程的控制是一样的。