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