【问题标题】:Should you use break in switch case loops?你应该在 switch case 循环中使用 break 吗?
【发布时间】:2023-04-08 13:06:02
【问题描述】:

以 FizzBu​​zz 为例,for 循环内的这个 switch case 在每个 case 之后都使用 break。

for (num = 1; num <= 100000; num ++) {
    switch (true) {
        case (num % 15 == 0):
            console.log("FizzBuzz");
            break;
        case (num % 3 == 0):
            console.log("Fizz");
            break;
        case (num % 5 == 0):
            console.log("Buzz");
            break;
        default:
            console.log(num);
            break;
    }
}

在 Mozilla 的 docs 中,他们说...

与每个 case 标签关联的可选 break 语句确保 一旦匹配的语句出现,程序就会跳出 switch 在 switch 之后的语句处执行并继续执行。如果 省略break,程序在下一个继续执行 switch 语句中的语句。

我假设它们的意思是当脚本检查 num % 15 == 0 时,如果没有中断并且即使它匹配 true,它也会转到 num % 3 ==0 等等。所以我用 100,000 个数字做了两次测试。一个有休息时间,一个没有休息时间。

我发现 break 和 no break 之间的差异大约为 2 秒,break 更短更快。但这是经过多次迭代。

我的问题是,对于大多数构建小型应用程序的开发人员来说,在他们的循环中使用中断真的很重要吗?这是习惯和偏好的问题吗?想法?

【问题讨论】:

  • 不,如果没有break - 它将无条件地执行以下所有case 主体,直到遇到第一个break,或者switch 块结束。
  • 这不是性能问题,而是功能差异。

标签: javascript loops switch-statement


【解决方案1】:

当在 switch 语句中满足case 条件时,它将执行该 switch 语句中的所有代码块,直到它遇到退出命令(想想break 或return)。所以break 不仅改变了性能速度,还改变了功能。

考虑 switch 语句的一种简单方法是替代链接的if-else 语句。

您的switch 代码也可以轻松编写

if (num % 15 == 0) {
   console.log("FizzBuzz");
} else if (num % 3 == 0) {
    console.log("Fizz");
} else if (num % 5 == 0) {
    console.log("Buzz");
} else {
    console.log(num);
}

如果您删除 break; 语句,您将更改代码的实际运行方式。它会表现得更像

if (num % 15 == 0) {
   console.log("FizzBuzz");
}

if (num % 3 == 0 || num % 15 == 0) {
    console.log("Fizz");
}

if (num % 5 == 0 || num % 3 == 0 || num % 15 == 0) {
    console.log("Buzz");
} 

console.log(num);

主要区别在于缺少else 条件。

【讨论】:

  • 漂亮说。谢谢。
  • Callum 当我把这是一个 jsfiddle 时,如果你的陈述是真的,它不会像我期望的那样:jsfiddle.net/kty48k6p。例如,数字 15 不会产生“FizzBu​​zz”、“Fizz”和“Buzz”。
  • @ka-mok 我的第二个代码块应该产生 "FizzBu​​zz","Fizz", "Buzz", 15。就像你的jsfiddle一样。可能让您感到困惑的是,该号码是在其相关的“Fizz”和“Buzz”内容之后记录的。这是因为default: console.log(num); 是最后执行的块。
【解决方案2】:

无论有没有break,你都会得到不同的结果。如果没有break,它将通过num = 15,例如,它将打印出"FizzBuzz"、"Fizz"、"Buzz"和"15"。而对于break,它只会打印出"FizzBuzz"。话虽如此,default 案例之后不需要休息,如果它在切换结束时。

【讨论】:

  • 请重新阅读此评论! “如果你省略了'break'语句,你的程序的逻辑是不同的 ...而且,毫无疑问,错了!”
  • "在默认情况下不需要休息" ...假设默认值结束,但它可以在开关中的任何位置。所以如果它没有结束,它确实需要休息
  • @MikeRobinson,这跟我说的有什么关系?
  • @MikeRobinson 不一定。可以无间断组合case,有目的地执行一个操作
  • “技术上是正确的,”查理,但是“如果我真的在你的源代码中看到这样的话,我会(充其量)对你非常恼火”没有令人难以置信的充分理由。 ;-)
【解决方案3】:

如果您不包含break 语句,那么您无疑引入了 a 错误(!) 进入你的程序!

原因如下:

如果您不包含break 语句,则逻辑将“简单地贯穿”到附加条件的代码中。 . . 但它不会(!)评估这些条件!它会直接崩溃,就像众所周知的瓷器店里的公牛一样。

换句话说,没有break 语句,(num % 15 == 0) 的情况将console.log() 四个(!!)(不是“一个”)消息.同样,(num % 3 == 0) 将记录 三个, 等等。

“嘿...别去那里。”

===== 编辑: 考虑switch 的原始("C...") 概念是“多路goto”的概念可能会有所帮助发生在构造的顶部,它分支到主体内的case 点之一。 break 语句生成了一个goto,将您发送到switch 的末尾。如果您不包含它,那么“有用”的假设是您打算做否则会发生的事情:一个case 会简单地“失败”到下一个。 (没有break,这正是它的作用。) “Caveat Coder!”

【讨论】:

  • 这根本不是错误。它可以是所需的功能。
  • 就是这样,无论有没有中断,都会产生相同的确切结果。我正在使用 Node.JS 的自定义构建器在 Sublime Text 3 上运行它
【解决方案4】:

详细说明卡勒姆·莫里森的回答:

当您返回一个案例中的值时,您可以优雅地删除break。

例如,

switch(expression) {
    case x:
        return *something*
    case y:
        return *something different*
}

这不会因为return 让您脱离声明而导致失败。在此示例中,您可以将 return 视为 break 的两倍。

如果您要在一个 case 中同时使用 return 和 break 的 switch 语句运行 linter,您将收到无法访问的代码错误,因为 return 在break 有机会执行。

// eslint
switch(expression) {
    case x:
        return *something*
        break; // error unreachable code
    case y:
        return *something different*
        break; // error unreachable code
}

【讨论】:

    猜你喜欢
    • 2018-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多