try/catch 块中的 return 语句如何工作?
function example() {
try {
return true;
}
finally {
return false;
}
}
我期待这个函数的输出是true
,但它是false
!
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
的行为。Completion 类型的值是(type, value, target)形式的三元组,其中type是 、 、 、 或 之一,value是任何ECMAScript语言值或空值,target是任何 ECMAScript 标识符或空值。return
throw
normal
break
continue
return
throw
很明显,return false
会将finally的完成类型设置为return,这会导致try ... finally
执行4. Return F。
当您使用finally
时,该块中的任何代码都会在方法退出之前触发。因为您在finally
块中使用返回,所以它调用return false
并覆盖块return true
中的前一个try
。
(术语可能不太正确。)
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
优先于函数的实际“返回”值。但是,这些返回值并不总是在您的代码中使用。
原因如下:
res.send()
Express.js,它创建一个 HTTP 响应并分派它。try
andfinally
块都会像这样执行这个函数: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
值与函数范围相关联。
恕我直言,您最好的选择是永远不要return
在finally
block内使用。它会使您的代码过于复杂并可能掩盖错误。
事实上,在 PHPStorm 中有一个默认的代码检查规则设置,它为此给出了“警告”:
https://www.jetbrains.com/help/phpstorm/javascript-and-typescript-return-inside-finally-block.html
finally
的?我finally
只会用来清理东西。任何对函数的返回值不重要的东西。
如果您考虑一下,这可能是有道理的,因为当您依赖 下的一行代码时finally
,您会假设try
or中可能存在错误catch
。但是最后两个是错误处理的实际构建块。只需使用return
intry
和catch
代替。
为什么你得到错误是你在 finally 块中返回。finally 块应该始终执行。所以你的return true
改变return false
function example() {
try {
return true;
}
catch {
return false;
}
}
据我所知,该finally
块始终执行,无论您return
内部是否有语句try
。因此,您将获得return
finally 块中的语句返回的值。
我在 Ubuntu 中使用 Firefox 3.6.10 和 Chrome 6.0.472.63 对此进行了测试。此代码在其他浏览器中的行为可能会有所不同。
从 finally 块返回
如果
finally
-block返回一个值,这个值就成为整个try-catch-finally
语句的返回值,不管 and -blockreturn
中的任何语句try
catch
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);
}
}