我已经阅读了很多关于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);
})
答案 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)
switch
和if/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"