为什么`finally`中的返回覆盖`try`?

时间:2010-10-01 09:36:41

标签: javascript return try-catch try-catch-finally try-finally

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

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

我希望此函数的输出为true,而是false

10 个答案:

答案 0 :(得分:78)

最后总是执行。这就是它的用途,这意味着它的回报会在你的情况下被使用。

您需要更改代码,因此更像是这样:

function example() { 
    var returnState = false; // initialisation value is really up to the design
    try { 
        returnState = true; 
    } 
    catch {
        returnState = false;
    }
    finally { 
        return returnState; 
    } 
} 

一般来说,你永远不希望在一个函数中有多个return语句,这就是为什么。

答案 1 :(得分:33)

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

  

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

     
      
  1. 设B为评估Block的结果。
  2.   
  3. 设F为最终评估的结果。
  4.   
  5. 如果F.type正常,则返回B.
  6.   
  7. 返回F.
  8.   

从第36页开始:

  

完成类型用于解释执行非本地控制转移的语句(breakcontinuereturnthrow)的行为。完成类型的值是(类型,值,目标)形式的三元组,其中类型normal之一,break,{ {1}},continuereturn是任何ECMAScript语言值或为空,目标是任何ECMAScript标识符或为空。

很明显,throw会将最终的完成类型设置为 return ,这会导致return false执行 4。返回F

答案 2 :(得分:12)

当您使用finally时,该方法中的任何代码都会在方法退出之前触发。由于您在finally块中使用了返回值,因此会调用return false并覆盖return true块中的上一个try

(术语可能不太正确。)

答案 3 :(得分:3)

为什么你变得虚假是你在一个finally块中返回的。 finally块应始终执行。所以return true更改为return false

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

答案 4 :(得分:1)

从finally代码段返回

如果finally块返回一个值,则该值将成为返回值 整个try-catch-finally语句的值,无论 returntry块中的catch条语句

参考:developer.mozilla.org

答案 5 :(得分:1)

我在这里给出一个略有不同的答案:是的,tryfinally块均被执行,并且finally优先于实际的“返回”值功能。但是,这些返回值并不总是在您的代码中使用。

这是为什么:

  • 下面的示例将使用Express.js中的res.send(),它创建HTTP响应并将其分派。
  • 您的tryfinally块都将像这样执行此功能:
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 。它将使您的代码过于复杂,并可能掩盖错误。

实际上,PHPStorm中有一个默认的代码检查规则设置,为此提供了“警告”:

https://www.jetbrains.com/help/phpstorm/javascript-and-typescript-return-inside-finally-block.html

那么您将finally用于什么呢?

我只会用finally来清理东西。对于函数的返回值不重要的任何事情。

考虑一下可能是有道理的,因为当您依赖finally下的一行代码时,您假设trycatch中可能存在错误。但是最后两个是错误处理的实际构建块。只需在returntry中使用catch

答案 6 :(得分:0)

据我所知,无论finally内是否有return语句,try阻止始终都会执行。你会得到finally块中return语句返回的值。

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

答案 7 :(得分:0)

finally块重写try块返回(从形象上来说)。

只是要指出,如果您从finally返回某项,那么它将从函数中返回。但是,如果最后没有“ return”字样,它将从try块中返回该值;

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

因此-finally- return重写了-try- return的返回结果。

答案 8 :(得分:-2)

最后应该总是在try catch块的末尾运行,以便(通过规范)是你返回false的原因。请记住,不同的浏览器完全有可能有不同的实现。

答案 9 :(得分:-3)

那呢?

doubleReturn();

function doubleReturn() {
  let sex = 'boy';

  try {
    return sex;

    console.log('this never gets called...');
  } catch (e) {} finally {
    sex = 'girl'; 

    alert(sex);
  }
}