为什么在使用 Switch 时需要 Break?

Joe*_*han 5 javascript switch-statement

我已经阅读了很多关于 SO 的答案,但似乎无法找到明确的答案,为什么如果在这种情况下省略了 break,则案例“C”将始终被评估为真,而填充的新数组只会“G” ”的。我清楚地明白,最好在这里使用 break,因为我只想评估特定的匹配,而不是为了如果确实省略了 break,为什么最后一种情况总是正确的。

 var dna = "ATTGC";
 var outArr = [];
 dna.split("").forEach(function(e,i){
    switch(e) {
        case "G": outArr[i] = "C"; break;
        case "T": outArr[i] = "A"; break;
        case "A": outArr[i] = "T"; break;
        case "C": outArr[i] = "G"; break;
    }
    console.log(outArr);
  })
Run Code Online (Sandbox Code Playgroud)

小智 7

来自 MDN

如果找到匹配项,程序将执行相关的语句。如果多个 case 与提供的值匹配,则选择第一个匹配的 case,即使这些 case 彼此不相等。

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

所以关于Switch的基本历史是它起源于C,是分支表的抽象,分支表也有隐含的fall-through,需要额外的跳转指令来避免。此外,所有其他语言继承 switch 作为默认 C 开关语义,主要选择保留默认的 C 语义。因此,在您的 switch 中,如果在所有情况下都省略了 break,则如果找到匹配项,程序将继续执行下一条语句。找到匹配项后,它不会从 switch 退出,而是评估匹配案例下方的所有其他案例,因为解析器认为案例已组合,因为它们之间没有中断。为了清楚地解释这种行为,我稍微修改了您的代码A。如果省略了中断。

var dna = "ATTGC";
var outArr = [];
dna.split("").forEach(function(e,i){
switch(e) {
    case "G": outArr[i] = "C"; break;
    case "T": outArr[i] = "A"; break;
    case "A": outArr[i] = "T";
    case "C": outArr[i] = "G"; break;
}
console.log(outArr);
})
Run Code Online (Sandbox Code Playgroud)

所以你的输出会像

["G"]
["G", "A"]
["G", "A", "A"]
["G", "A", "A", "C"]
["G", "A", "A", "C", "G"]
Run Code Online (Sandbox Code Playgroud)

在第一次迭代中,匹配将适用于案例A

outArr={'T'}
Run Code Online (Sandbox Code Playgroud)

同样,由于没有break语句,它会将 Case C视为同一块并继续执行。现在

outArr={'G'}
Run Code Online (Sandbox Code Playgroud)

类似地,在第二次迭代中,它与 case T匹配,但有一个break语句,因此控件跳出 switch 并且 outarr 现在将是

outArr={'G','A'}
Run Code Online (Sandbox Code Playgroud)

同样,对于其他迭代,您将获得上面发布的整个输出。

在这里更新了 Bin

  • 是否存在您想要省略“break”的有用情况?看起来省略 `break` 只会导致错误行为,那么为什么该关键字是可选的呢? (2认同)

Jos*_*ung 1

当一个case匹配的时候,如果不break的话,不管是否符合条件,都会继续执行下一个case。所以它们都会遇到最后一种情况,输出将被“G”覆盖