使用Switch时为什么需要Break?

时间:2016-09-28 21:16:08

标签: javascript switch-statement

我已经阅读了很多关于SO的答案,但似乎无法找到一个明确的答案,为什么如果在这种情况下省略break,则“C”将始终被评估为true并且新数组将被填充只有“G”的。我清楚地明白,破解最好在这里使用,因为我只想评估一个特定的匹配,但不是为什么如果确实省略了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);
  })

3 个答案:

答案 0 :(得分:2)

来自MDN

  

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

     

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

所以关于 Switch 的基本历史是它源于C并且是branch table的抽象,并且分支表也有隐含的掉落和需要一个额外的跳转指令来避免它。 此外,所有其他语言都继承了switch作为默认的C开关语义,大多数情况下选择保持默认的C语义。 所以在你的开关中,如果在所有情况下都省略了break,如果找到匹配,则程序继续执行下一个语句。找到匹配后它不会从开关退出,而是在匹配的情况下评估所有其他情况,因为解析器认为情况合并,因为它们之间没有中断 。 我已经修改了你的代码,以便清楚地解释这种行为。如果 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);
})

所以你的输出就像

["G"]
["G", "A"]
["G", "A", "A"]
["G", "A", "A", "C"]
["G", "A", "A", "C", "G"]

在第一次迭代中,匹配将是 A 的情况。

outArr={'T'}

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

outArr={'G'}

Similalrly在第二次迭代中匹配case T ,但是有一个 break 语句,所以控件跳出开关,outarr现在将

outArr={'G','A'}

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

  

更新了Bin here

答案 1 :(得分:1)

switchif/else在某种程度上是可以互换的,除了break在交换机中允许的内容之外。在和if/elseif/elseif/..../else链中,只有 ONE 块才能执行,例如

x = 7;
if (x == 5) {
    ... no match, not executed at all
} else if (x == 7) {
   .... match made, this is executed
} else if (x == 7) {
   ... this will not execute, because the other block already did
} else {
   ... this also never executes, because a match was made earlier
}

相比之下,使用switch,一旦匹配,就不会进行进一步的比较测试,并且将执行以下所有代码,直到切换块关闭(}),或者遇到break

x = 7;
switch(x) {
    case 5:   ... nothing matched, not executed; break;
    case 7: do_something();
    case 8: other_stuff();
    case 9: foo(); break;
    case 7: ... will not execute, because matching stopped above.
    default: stuff();
}

请注意break行上缺少case 7。这意味着继续执行,并忽略所有进一步的case行。这意味着执行do_something(),然后other_stuff()执行,foo()执行。最后遇到一个break,它终止了这个长期运行的case,然后继续执行switch之后发生的任何事情。

答案 2 :(得分:0)

当案件匹配时,如果你不打破,它将继续进入下一个案件,无论它是否与条件匹配。所以他们都将击中最后一个案例,输出将被覆盖" G"