为什么使用 Switch 时需要 Break?

2022-01-19 00:00:00 switch-statement javascript

我已经阅读了很多关于 SO 的答案,但似乎找不到明确的答案来解释为什么如果在这种情况下省略 break,则情况C"将始终被评估为 true,并且填充的新数组将只有G".我清楚地知道,这里最好使用 break ,因为我只是想评估一个特定的匹配,而不是如果确实省略了 break 为什么最后一种情况总是正确的.

I've read quite a few answers on SO but can't seem to find a definitive answer as to why if break is omitted in this instance the case "C" will always be evaluated as true and the new array filled will only "G"'s. I clearly understand that break would be best used here as I am only looking to evaluate a specific match but not so as to why the last case is always true if break is indeed omitted.

 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);
  })

推荐答案

来自 MDN

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

If a match is found, the program executes the associated statements. If multiple cases match the provided value, the first case that matches is selected, even if the cases are not equal to each other.

与每个 case 标签关联的可选 break 语句确保程序在执行匹配的语句后跳出 switch,并在 switch 后面的语句处继续执行.如果省略了break,程序将继续执行switch语句中的下一条语句.

The optional break statement associated with each case label ensures that the program breaks out of switch once the matched statement is executed and continues execution at the statement following switch. If break is omitted, the program continues execution at the next statement in the switch statement.

所以关于Switch的基本历史是它起源于C并且是branch table 和一个branch table 也有一个隐式的fall-through,需要额外的跳转指令来避免它.此外,所有其他语言都继承了 switch 作为默认的 C switch 语义,大多选择默认保留 C 语义.因此,如果在所有情况下都省略了 break,则在您的 switch 中,如果找到匹配项,则程序将继续执行下一条语句.找到匹配项后它不会退出 switch,而是评估匹配情况下的所有其他情况,因为 解析器认为情况是合并的,因为它们之间没有中断.为了清楚地解释这种行为,我对您的代码进行了一些修改.如果省略了 A 中断.

So the basic history about Switch is it originated from C and is an abstraction of branch table and a branch table also has an implicit fall-through and requires an additional jump instruction to avoid it. Also all other languages inherited switch as default C switch semantics mostly choosing to keep the C semantics per default. So in your switch if break is omitted from all cases, if the match is found program continues execution for next statement. It doesn't exit from switch after the match is found instead it evaluates all other case below the matched case, as parser thinks cases are combined, since there is no break in between them. I have modified your code a bit for clear explanation of this behavior.In case A break is omitted.

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);
})

所以你的输出会是这样的

So your Output will be like

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

在第一次迭代中,匹配将针对情况 A.

In first iteration match will be for case A.

outArr={'T'}

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

Again Since there is no break statement, it will consider Case C as same block and continues execution there. Now

outArr={'G'}

在第二次迭代中,它与 case T 相匹配,但有一个 break 语句,因此控件跳出开关,现在将是 outarr

Similalrly in second iteration it matches for case T but there is a break statement so controls jumps out of the switch and outarr will now be

outArr={'G','A'}

与其他迭代类似,您将获得上面发布的整个输出.

Similarly for other iterations you will get the whole output as posted above.

更新 Bin 这里

相关文章