How does a return statement inside a try/catch block work?
function example() {
try {
return true;
}
finally {
return false;
}
}
I'm expecting the output of this function to be true
, but instead it is false
!
Finally always executes. That's what it's for, which means it's return gets used in your case.
You'll want to change your code so it's more like this:
function example() {
var returnState = false; // initialisation value is really up to the design
try {
returnState = true;
}
catch {
returnState = false;
}
finally {
return returnState;
}
}
Generally speaking you never want to have more than one return statement in a function, things like this are why.
According to ECMA-262 (5ed, December 2009), in pp. 96:
The production
TryStatement : try Block Finally
is evaluated as follows:
- Let B be the result of evaluating Block.
- Let F be the result of evaluating Finally.
- If F.type is normal, return B.
- Return F.
And from pp. 36:
The Completion type is used to explain the behaviour of statements (
break
,continue
,return
andthrow
) that perform nonlocal transfers of control. Values of the Completion type are triples of the form (type, value, target), where type is one ofnormal
,break
,continue
,return
, orthrow
, value is any ECMAScript language value or empty, and target is any ECMAScript identifier or empty.
It's clear that return false
would set completion type of finally as return, which cause try ... finally
to do 4. Return F.
When you use finally
, any code within that block fires before the method exits. Because you're using a return in the finally
block, it calls return false
and overrides the previous return true
in the try
block.
(Terminology might not be quite right.)
why you are getting false is you returned in a finally block. finally block should execute always. so your return true
changes to return false
function example() {
try {
return true;
}
catch {
return false;
}
}
As far as I know, the finally
block always executes, irrespective of whether you have a return
statement inside try
or not. Ergo, you get the value returned by the return
statement inside finally block.
I tested this with Firefox 3.6.10 and Chrome 6.0.472.63 both in Ubuntu. It is possible that this code may behave differently in other browsers.
The finally block rewrites try block return (figuratively speaking).
Just wanted to point out, that if you return something from finally, then it will be returned from the function. But if in finally there is no 'return' word - it will be returned the value from try block;
function example() {
try {
return true;
}
finally {
console.log('finally')
}
}
console.log(example());
// -> finally
// -> true
So -finally- return
rewrites the return of -try- return
.
Finally is supposed to ALWAYS run at the end of a try catch block so that (by specification) is why you are getting false returned. Keep in mind that it is entirely possible that different browsers have different implementations.
What about this?
doubleReturn();
function doubleReturn() {
let sex = 'boy';
try {
return sex;
console.log('this never gets called...');
} catch (e) {} finally {
sex = 'girl';
alert(sex);
}
}
来源:https://stackoverflow.com/questions/3837994/why-does-a-return-in-finally-override-try