try / catch块中的return语句如何工作?
function example() {
try {
return true;
}
finally {
return false;
}
}
我期待这个函数的输出是true
,但它是false
!
最后总是执行。这就是它的用途,这意味着它的回报会在你的情况下被使用。
你会想要改变你的代码,所以它更像是这样的:
function example() {
var returnState = false; // initialisation value is really up to the design
try {
returnState = true;
}
catch {
returnState = false;
}
finally {
return returnState;
}
}
一般来说,你永远不希望在一个函数中有多个return语句,这就是为什么。
根据ECMA-262(5ed,2009年12月),第96页:
生产
TryStatement : try Block Finally
评估如下:
- 设B是评估Block的结果。
- 设F为最终评估的结果。
- 如果F.type正常,则返回B.
- 返回F.
从第36页开始:
Completion类型用于解释执行非局部控制转移的语句(
break
,continue
,return
和throw
)的行为。完成类型的值是形式(类型,值,目标)的三元组,其中类型是normal
,break
,continue
,return
或throw
之一,值是任何ECMAScript语言值或为空,target是任何ECMAScript标识符或空。
很明显,return false
将最终的完成类型设置为返回,这会导致try ... finally
做4.返回F.
当您使用finally
时,该方法块中的任何代码都会在方法退出之前触发。因为你在finally
块中使用了一个返回值,所以它调用return false
并覆盖return true
块中的前一个try
。
(术语可能不太正确。)
为什么你变得虚假是你在最后一个块中返回。 finally块应始终执行。所以你的return true
改为return false
function example() {
try {
return true;
}
catch {
return false;
}
}
据我所知,finally
块总是执行,无论你是否在return
内都有try
语句。你会得到最后一个块里面的return
语句返回的值。
我在Ubuntu中使用Firefox 3.6.10和Chrome 6.0.472.63对此进行了测试。此代码可能在其他浏览器中的行为有所不同。
finally块重写try块返回(比喻说)。
只是想指出,如果你从最后返回一些东西,那么它将从函数返回。但如果最终没有“返回”字 - 它将从try块返回值;
function example() {
try {
return true;
}
finally {
console.log('finally')
}
}
console.log(example());
// -> finally
// -> true
所以-finally-return
重写了-try- return
的回归。
最后应该总是在try catch块的末尾运行,以便(通过规范)是你返回false的原因。请记住,不同的浏览器完全有可能有不同的实现。
那这个呢?
doubleReturn();
function doubleReturn() {
let sex = 'boy';
try {
return sex;
console.log('this never gets called...');
} catch (e) {} finally {
sex = 'girl';
alert(sex);
}
}