Try/catch 块中的 return 语句是如何工作的?
function example() { try { return true; } finally { return false; } }
我期望这个函数的输出是 true,但实际上它是 false!
true
false
使用 finally时,该块中的任何代码都会在方法退出之前触发。因为您在 finally块中使用了一个返回值,所以它调用 return false并覆盖 try块中以前的 return true。
finally
return false
try
return true
(术语可能不太对。)
据我所知,无论您在 try中是否有 return语句,finally块 一直都是都会执行。因此,您将获得 finally 块中的 return语句返回的值。
return
我在 Ubuntu 中用 Firefox 3.6.10和 Chrome 6.0.472.63测试了这个。这段代码在其他浏览器中的行为可能有所不同。
为什么你会得到假的是你返回了一个 finally 块。Finally 块应该始终执行。所以你的 return true变成了 return false
function example() { try { return true; } catch { return false; } }
最后应该总是在 try catch 块的末尾运行,这样(根据规范)就会得到错误返回。请记住,不同的浏览器完全有可能有不同的实现。
最后执行 一直都是,这就是它的作用,这意味着它的返回值将在您的情况下使用。
你需要改变你的代码,让它更像这样:
function example() { var returnState = false; // initialization value is really up to the design try { returnState = true; } catch { returnState = false; } finally { return returnState; } }
一般来说,一个函数中永远不要有多个 return 语句,这就是原因。
根据 ECMA-262(2009年12月第5版) ,第96页:
TryStatement : try Block Finally的生产情况评估如下: 设 B 为求块的结果。 设 F 是最终评估的结果。 如果 F 类型正常,返回 B。 回程 F。
TryStatement : try Block Finally的生产情况评估如下:
TryStatement : try Block Finally
第36页:
Completion 类型用于解释执行非本地控制转移的语句(break、 continue、 return和 throw)的行为。Completion 类型的值是形式 (类型、值、目标)的三元组,其中 continue0是 normal、 break、 continue、 return或 throw中的一个,continue1是任何 ECMAScript 语言值或空,而 continue2是任何 ECMAScript 标识符或空。
break
continue
throw
normal
很明显,return false将 终于的完成类型设置为 返回,这导致 try ... finally做 4. 返回 F。
try ... finally
Finally 块重写 try 块 return (形象地说)。
只是想指出,如果从 finally 返回某个值,那么它将从函数返回。但是如果在最后没有返回字-它将返回的值从 try 块;
function example() { try { return true; } finally { console.log('finally') } } console.log(example()); // -> finally // -> true
因此-finally-return重写-try-return的返回值。
从 finally-block 返回 如果 finally块返回一个值,则该值将成为返回值 整个 try-catch-finally语句的值,而不管任何 try和 catch块中的 return语句
从 finally-block 返回
如果 finally块返回一个值,则该值将成为返回值 整个 try-catch-finally语句的值,而不管任何 try和 catch块中的 return语句
try-catch-finally
catch
参考资料: Developer.mozilla.org
这里我要给出一个稍微不同的答案: 是的,try和 finally块都得到了执行,而且 finally优先于函数的实际“ return”值。但是,这些返回值并不总是在代码中使用。
原因如下:
res.send()
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值与函数范围相关联。
我认为你最好的选择是 不要在 ABC1块中使用 return。它会使你的代码过于复杂并且可能掩盖错误。
事实上,在 PHPStorm 中有一个默认的代码检查规则设置,为此提供了一个“警告”:
Https://www.jetbrains.com/help/phpstorm/javascript-and-typescript-return-inside-finally-block.html
我将使用 finally只清理东西。任何不是关键的返回值的函数。
如果您仔细想想,这可能是有意义的,因为当您依赖于 finally下的一行代码时,您假设 try或 catch中可能存在错误。但是最后两个是错误处理的实际构建块。只需在 try和 catch中使用 return即可。