try/catch 块中的 return 语句如何工作?
function example() {
try {
return true;
}
finally {
return false;
}
}
我希望这个函数的输出是 true
,但实际上是 false
!
最后总是执行。这就是它的用途,这意味着它的返回值会在您的情况下使用。
您需要更改代码,使其更像这样:
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 为评估 Block 的结果。令 F 为 Final 评估的结果。如果 F.type 正常,返回 B。返回 F。
从第 36 页开始:
Completion 类型用于解释执行非本地控制转移的语句(break、continue、return 和 throw)的行为。 Completion 类型的值是 (type, value, target) 形式的三元组,其中 type 是 normal、break、continue、return 或 throw 之一,value 是任何 ECMAScript 语言值或空值,target 是任何 ECMAScript 标识符或空的。
很明显,return false
会将 finally 的完成类型设置为 return,这会导致 try ... finally
执行 4。返回 F。
当您使用 finally
时,该块中的任何代码都会在方法退出之前触发。因为您在 finally
块中使用了 return,所以它调用 return false
并覆盖 try
块中的前一个 return true
。
(术语可能不太正确。)
finally 块重写了 try 块返回(形象地说)。
只是想指出,如果你从 finally 返回一些东西,那么它将从函数中返回。但是如果在 finally 中没有'return' 字 - 它将返回来自 try 块的值;
function example() {
try {
return true;
}
finally {
console.log('finally')
}
}
console.log(example());
// -> finally
// -> true
所以 -finally- return
重写了 -try- return
的返回值。
我将在这里给出一个稍微不同的答案:是的,try
和 finally
块都被执行,并且 finally
优先于函数的实际“返回”值。但是,这些返回值并不总是在您的代码中使用。
原因如下:
下面的示例将使用 Express.js 中的 res.send(),它创建一个 HTTP 响应并分派它。
你的 try 和 finally 块都会像这样执行这个函数:
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
值与函数范围相关联。
恕我直言,您最好的选择是永远不要在 finally
块中使用 return
。它会使您的代码过于复杂并可能掩盖错误。
事实上,在 PHPStorm 中有一个默认的代码检查规则设置,它为此给出了“警告”:
https://www.jetbrains.com/help/phpstorm/javascript-and-typescript-return-inside-finally-block.html
那你最后用什么?
我只会使用 finally
来清理东西。任何对函数的返回值不重要的东西。
如果您考虑一下,这可能是有道理的,因为当您依赖 finally
下的一行代码时,您假设 try
或 catch
中可能存在错误。但是最后两个是错误处理的实际构建块。只需在 try
和 catch
中使用 return
。
为什么你得到错误是你在 finally 块中返回。 finally 块应该始终执行。所以您的 return true
更改为 return false
function example() {
try {
return true;
}
catch {
return false;
}
}
从 finally 块返回 如果 finally 块返回一个值,该值将成为整个 try-catch-finally 语句的返回值,而不管 try 和 catch 块中的任何 return 语句
据我所知,无论您在 try
中是否有 return
语句,finally
块始终 都会执行。因此,您会在 finally 块中获得 return
语句返回的值。
我在 Ubuntu 中使用 Firefox 3.6.10 和 Chrome 6.0.472.63 对此进行了测试。此代码在其他浏览器中的行为可能会有所不同。
finally 应该总是在 try catch 块的末尾运行,这样(根据规范)就是你得到错误返回的原因。请记住,不同的浏览器完全有可能具有不同的实现。
那这个呢?
doubleReturn();
function doubleReturn() {
let sex = 'boy';
try {
return sex;
console.log('this never gets called...');
} catch (e) {} finally {
sex = 'girl';
alert(sex);
}
}
不定期副业成功案例分享