Javascript 为什么 `finally` 中的 return 会覆盖 `try`?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3837994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:19:43  来源:igfitidea点击:

Why does a return in `finally` override `try`?

javascriptreturntry-catchtry-catch-finallytry-finally

提问by bonfo

How does a return statement inside a try/catch block work?

try/catch 块中的 return 语句如何工作?

function example() {
    try {
        return true;
    }
    finally {
        return false;
    }
}

I'm expecting the output of this function to be true, but instead it is false!

我期待这个函数的输出是true,但它是false

回答by annakata

Finally alwaysexecutes. That's what it's for, which means it's return gets used in your case.

最后总是执行。这就是它的用途,这意味着它的 return 在您的情况下被使用。

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.

一般来说,你永远不想在一个函数中有多个 return 语句,这就是原因。

回答by livibetter

According to ECMA-262 (5ed, December 2009), in pp. 96:

根据 ECMA-262(2009 年 12 月第 5 版),第 96 页:

The production TryStatement : try Block Finallyis evaluated as follows:

  1. Let B be the result of evaluating Block.
  2. Let F be the result of evaluating Finally.
  3. If F.type is normal, return B.
  4. Return F.

生产TryStatement : try Block Finally评估如下:

  1. 令 B 为评估 Block 的结果。
  2. 令 F 为最终求值的结果。
  3. 如果 F.type 正常,则返回 B。
  4. 返回 F。

And from pp. 36:

从第 36 页:

The Completion type is used to explain the behaviour of statements (break, continue, returnand throw) that perform nonlocal transfers of control. Values of the Completion type are triples of the form (type, value, target), where typeis one of normal, break, continue, return, or throw, valueis any ECMAScript language value or empty, and targetis any ECMAScript identifier or empty.

完成类型用于解释语句(行为breakcontinuereturnthrow)来实现控制的非局部传输。Completion 类型的值是(type, value, target)形式的三元组,其中typenormal, break, continue, return, or 之一throwvalue是任何 ECMAScript 语言值或空,target是任何 ECMAScript 标识符或空。

It's clear that return falsewould set completion type of finallyas return, which cause try ... finallyto do 4. Return F.

很明显,return falsefinally 的完成类型设置为return,这会导致try ... finally执行4. Return F

回答by djdd87

When you use finally, any code within that block fires before the method exits. Because you're using a return in the finallyblock, it calls return falseand overrides the previous return truein the tryblock.

当您使用 时finally,该块中的任何代码都会在该方法退出之前触发。因为你使用的返回finally块,它会调用return false并覆盖以前return truetry块。

(Terminology might not be quite right.)

(术语可能不太正确。)

回答by anishMarokey

why you are getting false is you returned in a finally block. finally block should execute always. so your return truechanges to return false

为什么你得到 false 是你在 finally 块中返回。finally 块应该始终执行。所以你的return true改变return false

function example() {
    try {
        return true;
    }
    catch {
        return false;
    }
}

回答by Mihey Mik

The finally block rewrites try block return (figuratively speaking).

finally 块重写了 try 块 return(形象地说)。

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;

只是想指出,如果你从 finally 返回一些东西,那么它将从函数中返回。但是如果在 finally 中没有“返回”字样 - 它将从 try 块返回值;

function example() {
    try {
        return true;
    }
    finally {
       console.log('finally')
    }
}
console.log(example());
// -> finally
// -> true

So -finally- returnrewrites the return of -try- return.

所以 -finally-return重写了-try-的返回值return

回答by Manoj Govindan

As far as I know, the finallyblock alwaysexecutes, irrespective of whether you have a returnstatement inside tryor not. Ergo, you get the value returned by the returnstatement inside finally block.

据我所知,无论您是否在内部有语句,finally总是会执行。因此,您将获得finally 块中的语句返回的值。returntryreturn

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.

我在 Ubuntu 中使用 Firefox 3.6.10 和 Chrome 6.0.472.63 对此进行了测试。此代码在其他浏览器中的行为可能有所不同。

回答by Tho

Returning from a finally-block

If the finally-block returns a value, this value becomes the return value of the entire try-catch-finallystatement, regardless of any returnstatements in the tryand catch-blocks

从 finally 块返回

如果finally-block 返回一个值,则该值成为整个try-catch-finally语句的返回值,而不管和-blocks 中的任何 return语句trycatch

Reference: developer.mozilla.org

参考:developer.mozilla.org

回答by Darko Z

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.

最后应该总是在 try catch 块的末尾运行,这样(按规范)就是为什么你得到 false 返回。请记住,完全有可能不同的浏览器有不同的实现。

回答by Thomas Karlsson

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);
  }
}