127

try/catch 块中的 return 语句如何工作?

function example() {
    try {
        return true;
    }
    finally {
        return false;
    }
}

我期待这个函数的输出是true,但它是false

4

10 回答 10

116

最后总是执行。这就是它的用途,这意味着它的返回值会在您的情况下使用。

您需要更改代码,使其更像这样:

function example() { 
    var returnState = false; // initialization value is really up to the design
    try { 
        returnState = true; 
    } 
    catch {
        returnState = false;
    }
    finally { 
        return returnState; 
    } 
} 

一般来说,你永远不想在一个函数中有多个 return 语句,这样的事情就是原因。

于 2010-10-01T09:45:35.060 回答
50

根据 ECMA-262(2009 年 12 月第 5 版),第 96 页:

生产TryStatement : try Block Finally评估如下:

  1. 令 B 为评估 Block 的结果。
  2. 令 F 为 Final 评估的结果。
  3. 如果 F.type 正常,则返回 B。
  4. 返回 F。

从第 36 页开始:

Completion 类型用于解释执行非本地控制转移的语句( 、 和breakcontinue的行为。Completion 类型的值是(type, value, target)形式的三元组,其中type是 、 、 、 或 之一,value是任何ECMAScript语言值或空值,target是任何 ECMAScript 标识符或空值。returnthrownormalbreakcontinuereturnthrow

很明显,return false会将finally的完成类型设置为return,这会导致try ... finally执行4. Return F

于 2010-10-01T09:56:49.817 回答
18

当您使用finally时,该块中的任何代码都会在方法退出之前触发。因为您在finally块中使用返回,所以它调用return false并覆盖块return true中的前一个try

(术语可能不太正确。)

于 2010-10-01T09:42:42.117 回答
7

finally 块重写了 try 块返回(形象地说)。

只是想指出,如果你从 finally 返回一些东西,那么它将从函数中返回。但是如果在 finally 中没有'return' 字 - 它将返回来自 try 块的值;

function example() {
    try {
        return true;
    }
    finally {
       console.log('finally')
    }
}
console.log(example());
// -> finally
// -> true

所以 -finally-return重写了 -try- 的返回值return

于 2019-03-19T08:45:21.360 回答
4

我将在这里给出一个稍微不同的答案:是的,tryfinally块都被执行,并且finally优先于函数的实际“返回”值。但是,这些返回值并不总是在您的代码中使用。

原因如下:

  • 下面的示例将使用res.send()Express.js,它创建一个 HTTP 响应并分派它。
  • 你的tryandfinally块都会像这样执行这个函数:
try {
    // Get DB records etc.
    return res.send('try');
} catch(e) {
    // log errors
} finally {
    return res.send('finally');
}

try此代码将在您的浏览器中显示该字符串。此外,该示例将在您的控制台中显示错误。该res.send()函数被调用两次。任何作为函数的东西都会发生这种情况。try-catch-finally 块会使未经训练的人混淆这个事实,因为(个人)我只将return值与函数范围相关联。

恕我直言,您最好的选择是永远不要returnfinallyblock内使用。它会使您的代码过于复杂并可能掩盖错误。

事实上,在 PHPStorm 中有一个默认的代码检查规则设置,它为此给出了“警告”:

https://www.jetbrains.com/help/phpstorm/javascript-and-typescript-return-inside-finally-block.html

那你是干什么用finally的?

finally只会用来清理东西。任何对函数的返回值不重要的东西。

如果您考虑一下,这可能是有道理的,因为当您依赖 下的一行代码时finally,您会假设tryor中可能存在错误catch。但是最后两个是错误处理的实际构建块。只需使用returnintrycatch代替。

于 2020-06-25T22:16:25.087 回答
3

为什么你得到错误是你在 finally 块中返回。finally 块应该始终执行。所以你的return true改变return false

function example() {
    try {
        return true;
    }
    catch {
        return false;
    }
}
于 2010-10-01T09:43:33.397 回答
1

据我所知,该finally始终执行,无论您return内部是否有语句try。因此,您将获得returnfinally 块中的语句返回的值。

我在 Ubuntu 中使用 Firefox 3.6.10 和 Chrome 6.0.472.63 对此进行了测试。此代码在其他浏览器中的行为可能会有所不同。

于 2010-10-01T09:43:22.197 回答
1

从 finally 块返回

如果finally-block返回一个值,这个值就成为整个try-catch-finally语句的返回值,不管 and -blockreturn中的任何语句trycatch

参考:developer.mozilla.org

于 2020-03-14T16:52:08.547 回答
-2

finally 应该总是在 try catch 块的末尾运行,这样(根据规范)就是你得到错误返回的原因。请记住,不同的浏览器完全有可能具有不同的实现。

于 2010-10-01T09:43:56.337 回答
-3

那这个呢?

doubleReturn();

function doubleReturn() {
  let sex = 'boy';

  try {
    return sex;

    console.log('this never gets called...');
  } catch (e) {} finally {
    sex = 'girl'; 

    alert(sex);
  }
}
于 2018-06-28T20:38:06.030 回答