【问题标题】:Is it better to wrap code into an 'IF' statement, or is it better to 'short circuit' the function and return? [closed]将代码包装到“IF”语句中更好,还是“短路”函数并返回更好? [关闭]
【发布时间】:2010-01-12 20:05:40
【问题描述】:

我正在使用 JavaScript 进行一些编码,并且在很多情况下我必须在继续之前检查一些内容。我养成了在函数中尽早返回的习惯,但我不确定我这样做是否正确。我不确定它是否会随着代码的增长而影响代码的复杂性。

我想从更有经验的 JavaScript 编码人员那里了解以下两个示例中更好的一般做法。或者它是无关紧要的,它们都是编写这个特定 IF 块的好方法?

1) 提前返回或我称之为“短路”(保护条款)。

ServeAlcohol = function(age)
{
     if(age < 19)
         return;


     //...Code here for serving alcohol.....
}

..或者...

2) 将代码包装到 IF 语句中。

ServeAlcohol = function(age)
{
     if(age >= 19)
     {
          //...Code here for serving alcohol.....
     }
}

【问题讨论】:

  • 只是说,第二种情况应该是age &gt;= 19
  • LOl 谢谢...否则不会为 19 岁的人提供服务。哈哈。
  • 就个人而言,我对您在问题标题中的问题的回答是“是”。
  • 当你发现有人愿意争论这两种情况时,这往往会演变成一场圣战。
  • 如果您想知道,这些被称为“保护条款”。并回答你的问题,“是的。”

标签: javascript coding-style


【解决方案1】:

通常我会立即返回输入验证。想象一下,如果你有一堆条件,你会立刻得到一堆嵌套的ifs。

通常,一旦我通过输入验证,我会避免多次返回,但为了验证,我会立即返回。恕我直言,保持清洁。

【讨论】:

  • +1 这是一个关于巨大嵌套 IF 块的好点。
  • 通常它只是一种编程风格,但正如答案所说,如果 IF 块很大,对于要维护代码的人来说并不明显。
  • +1 通常,最好让一段代码只有一条进出一条路。有一些常识性例外,预先验证就是其中之一。
  • @AnthonyWJones,为什么最好只有一种进出方式?
  • @Kevin:内存释放在 Java 中没有问题,因为垃圾收集器会为你做这件事。因此,手动内存管理是仅支持一个返回点的有力论据。但是在 Java 中……可读性较差是有问题的,并且很大程度上取决于情况。为了避免嵌套ifs,我更喜欢监护人。如果只检查一个条件,则 if 应该更好。
【解决方案2】:

我更喜欢第一个,因为它是一个守卫条件,你直接退出。但我不认为两者都存在性能问题,只是这是你的偏好......两者都会直接返回执行......

【讨论】:

    【解决方案3】:

    个人选择。对我来说,如果我可以在方法开始时检查一些“停止”条件,我更喜欢使用“返回”模式。但前提是我可以在方法的开头完成所有这些操作。

    【讨论】:

      【解决方案4】:

      FWIW,我会提出相反的意见。结构化编程建议一个函数应该有一个退出点。我认为如果您使用提前返回、break 语句、goto 语句等,有些编译器优化是不可用的。此外,代码中更多的分支意味着更难填充 CPU 管道,从而可能导致性能下降......还有一些不及早返回的原因来处理关于正确性的严格(即代数)推理。

      Structured Programming wiki article

      【讨论】:

      • -1。大多数努力遵循该范式的代码往往是一个多缩进不可读的混乱,呱呱叫“杀了我”......啊。基本上,您的观点很好,但不适用于所有情况的 99.9%。过早的优化等等。 (如果您的验证是热点,那么您还有其他问题。;)
      • 我对这些性能论点持怀疑态度。提前返回的代码没有更多的分支。它可能会编译成完全相同的代码。正确性论点也值得怀疑。异常打破了单返回假设的广泛开放——如今的语言具有 C# 中的 finallyusing、Python 中的 with 和 C++ 中的 RAII 模式等特性,即“这段代码无论如何都会运行”什么”明确地工作,即使面对异常或提前返回。
      • vicatcu 关于正确性论证是正确的:单出口代码更容易正式推理(Dijkstra 寻求它的一个原因)。他对管道冲洗问题也是正确的。一般来说,我发现从长远来看,仔细构建带有单出口代码的设置往往是最易于维护的。
      【解决方案5】:

      这真的取决于。我确实喜欢简单函数的一个返回点,但任何超过 10-20 行的内容,为了代码清晰起见,我将开始分解。

      【讨论】:

        【解决方案6】:

        我更喜欢第一个,因为它是消除的过程,在程序甚至必须逐步执行下一轮逻辑之前,您就从函数中返回。 我称它为我的prereq check - 如果不符合prereq check,函数将不会执行

        事实上,我一直都这样做,例如,经典的方法是我有一个函数,它需要一个整数,然后我得到一个字符串,我在函数的顶部检查它是否是整数,而不是如果它不是一个字符串,也不是另一个对象/类型,这在我的书中很愚蠢。

        这就像哈佛的大学申请,先决条件:

        'I don't want to even want you to come for an interview if you don't have a 3.5GPA or higher!'

        :=)

        【讨论】:

          【解决方案7】:

          第一个通常是首选,因为它减少了所需的缩进(这可能会失控)。没有真正的性能差异。

          【讨论】:

            【解决方案8】:

            有些人认为每个函数都应该有一个退出点。但是,我发现在开始时完成您提到的快速条件检查时会更清楚。它还避免了一些代码不必要地运行。

            【讨论】:

              【解决方案9】:

              我听说过的一般规则基本上是早期失败并且经常失败。你永远不知道什么时候有一行代码指向某个超重载的 setter,它的工作比你想象的要辛苦得多。如果您可以阻止该行代码被执行(例如,通过提早返回),那么您的代码将成倍提高效率。

              换句话说,如果您可以提前返回并阻止代码执行,请随时执行此操作 - 尤其是在您完全关心性能的情况下。我想这在 JS 之类的东西中可能不那么重要——我更像是一个 AS3 人——但同样的逻辑也适用。

              如果您有很多案例,最好也追踪每个案例中的故障点 - 在您的示例中,追踪由于年龄太低而提前返回。这将有助于其他进入并尝试调试您的代码的开发人员,他们会知道失败的地方和原因。

              希望对您有所帮助! :)

              【讨论】:

                【解决方案10】:

                另外,因为 JavaScript 是伪装的方案

                HandleRequestForAlcohol = function(age) { 
                    ( IsUnderAge(age) ? RespondUnderAge : ServeAlcohol )();
                }
                

                选择函数的习惯用法并不那么重要,如果您要进行复杂的验证然后有多个进程,请将它们分解为单独的函数,而不是制作一个大函数,除非它在性能非常关键的位代码。

                【讨论】:

                  【解决方案11】:

                  在我看来,作为最佳实践,我认为在控制块中始终使用大括号更为重要,即使它们的主体只有一行。

                  一致

                  if ( condition ) {
                      statement;
                      statement;
                  }
                  
                  if ( condition ) {
                      statement;
                  }
                  

                  不一致

                  if ( condition ) {
                      statement;
                      statement;
                  }
                  
                  if ( condition )
                      statement;
                  

                  但即便如此,这完全是主观的。

                  至于何时打破一个函数,以及缩进的级别,这也是主观的。研究和经验表明,仅在一个点(结尾)退出函数更容易调试、优化等。另一方面,多级缩进会使函数难以阅读。

                  【讨论】:

                    【解决方案12】:

                    如果有多个/复杂的守卫,我会使用返回。否则,在一个简单条件的情况下(在一个小函数中),我更喜欢使用 if。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2016-02-27
                      • 2011-03-21
                      • 1970-01-01
                      • 2020-09-15
                      相关资源
                      最近更新 更多