Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

try-catch-finally #38

Open
JChehe opened this issue May 14, 2019 · 0 comments
Open

try-catch-finally #38

JChehe opened this issue May 14, 2019 · 0 comments

Comments

@JChehe
Copy link
Owner

JChehe commented May 14, 2019

基础

try {
    // 可能会导致错误的代码
} catch (err) {
    // 在错误发生时怎么处理
} finally {
    // 无论是否报错都会执行
}

try-catch 是针对可能抛出错误代码,避免因报错而中断整体代码的运行。

try 不能单独使用,必须搭配 catchfinally 使用。

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 优先于 trythrowreturn

在 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 优先于(或取代了) tryreturn(上一小节是 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

从以上结果可看出,trycatchreturn 都需要先经过 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

可见,throwreturn 对代码执行流程的控制是一样的。

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant