回到课程
本资料仅提供以下语言版本:English, 日本語。请 帮助我们 将其翻译为 简体中文 版本。

在 `finally` 中执行,还是在直接放在代码后面

重要程度: 5

比较下面两个代码片段。

  1. finally 执行 try..catch 之后的代码:

    try {
      work work
    } catch (e) {
      handle errors
    } finally {
      cleanup the working space
    }
  2. 第二个代码片段,把清空工作空间的代码放在 try..catch 之后,但并不包裹在 finally 里面。

    try {
      work work
    } catch (e) {
      handle errors
    }
    
    cleanup the working space

我们只是需要在代码执行完之后,清除工作空间,而不管是不是在执行的过程中遇到异常。

那么,是用 finally 好呢还是两种方式都一样?如果哪种更好,请举例说明在什么情况下它会更好?

当我们看下面这个函数里面的代码,差异就很明显了。

如果能够跳出 try..catch,表现就不同了。

例如,当 try..catch 里有 return 的时候,finally 代码块会在退出 try..catch 后继续执行,即使是通过 return 语句退出的。它会在再后面的代码执行之前,在 try..catch 执行完之后立即执行。

function f() {
  try {
    alert('start');
    return "result";
  } catch (e) {
    /// ...
  } finally {
    alert('cleanup!');
  }
}

f(); // cleanup!

…或者当有 throw 的时候,如下:

function f() {
  try {
    alert('start');
    throw new Error("an error");
  } catch (e) {
    // ...
    if("can't handle the error") {
      throw e;
    }

  } finally {
    alert('cleanup!')
  }
}

f(); // cleanup!

正是这里的 finally 代码块保证了 cleanup 的显示,但是如果把 finally 里面的这行代码放在函数 f 的最后,那么,它不会执行。