为什么`finally`中的返回覆盖`try`?

bon*_*nfo 81 javascript return try-catch try-catch-finally try-finally

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

function example() {
    try {
        return true;
    }
    finally {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

我期待这个功能的输出true,但它是false!

ann*_*ata 82

最后总是执行.这就是它的用途,这意味着它的回报会在你的情况下被使用.

您需要更改代码,因此更像是这样:

function example() { 
    var returnState = false; // initialisation value is really up to the design
    try { 
        returnState = true; 
    } 
    catch {
        returnState = false;
    }
    finally { 
        return returnState; 
    } 
} 
Run Code Online (Sandbox Code Playgroud)

一般来说,你永远不希望在一个函数中有多个return语句,这就是为什么.

  • 我认为有多个返回声明并不总是坏的 - 有关更多讨论,请参阅http://stackoverflow.com/questions/36707/should-a-function-have-only-one-return-statement. (36认同)
  • +1好的答案.虽然在一个函数的一个回归上不同意. (6认同)
  • 我也不同意一条返回规则.你永远不应该从最后回来(在C#中,甚至不允许). (4认同)

liv*_*ter 35

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

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

  1. 设B是评估Block的结果.
  2. 设F为最终评估的结果.
  3. 如果F.type正常,则返回B.
  4. 返回F.

从第36页开始:

完成类型用于解释语句的行为(break,continue,returnthrow)来实现控制的非局部传输.于完成类型的值的形式为三元组(类型,值,目标),其中是以下之一normal,break,continue,return,或throw,是任何ECMAScript语言值或空的,并且目标是任何的ECMAScript标识符或为空.

很明显,return false将设置完成类型最后作为回报,导致try ... finally4.返回˚F.

  • 在阅读了这个问题的各种“基本正确但不知何故模糊且不明确”的答案后,这个答案实际上是有道理的。关键一点是,无论 try+catch 结束时“发生”什么(返回或抛出或只是正常流程),当它运行finally部分时,它都会被_记住_,然后只有在finally结束时没有发生任何事情时才会真正发生。 (4认同)

djd*_*d87 13

使用时finally,该方法中的任何代码都会在方法退出之前触发.因为你使用的返回finally块,它会调用return false并覆盖以前return truetry块.

(术语可能不太正确.)


Fla*_*ame 8

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

原因如下:

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

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

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

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

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

那么你有什么用finally呢?

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

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


Mih*_*Mik 6

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

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

function example() {
    try {
        return true;
    }
    finally {
       console.log('finally')
    }
}
console.log(example());
// -> finally
// -> true
Run Code Online (Sandbox Code Playgroud)

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