JavaScript中switch语句中的重复case问题

3
在回答这个问题时,最受欢迎的答案表明这是最好的方法:
switch(variable) {
    case 0:
        // operation A;
    case 1:
        // operation B;
        break;
}

但是如果操作B必须在操作A之前执行怎么办?在这种情况下,这样做是否可行,还是有更好的解决方案:

switch(variable) {
    case 0:
    case 1:
        // operation B;
        break;
    case 0:
        // operation A;
        break;
}

那么对于 case 0,您想要 B,然后是 A,而对于 case 1,您只想要 B?在这种情况下,我会考虑使用两个 switch 块,具体取决于其他 case 的数量。 - user5734311
@BorisLobanov 运行时不会出现错误,但这绝对不是完美的,这是一种糟糕的做法,也不能实现原本希望得到的行为。 - Matthew Ciaramitaro
3个回答

3

这个break语句将会使你跳出当前的switch语句,在这种情况下最好把操作进行两遍,像这样:

switch(variable){
    case 0:
       //operation B
       //Operation A
       break;
    case 1:
       // Operation A
       break;
}

最好的避免过多重复代码的方法是将操作A和操作B分开成不同的函数,这样只需要2行代码即可完成切换。
switch(variable){
    case 0:
       this.DoOperationB(variables)
       this.DoOperationA(variables)
       break;
    case 1:
       this.DoOperationA(variables)
       break;
}

在所有给出的答案中,这也是我个人会采用的方式:清晰易懂,避免了代码重复,并且函数通常是一个好东西。 - Marco
这个答案适用于我们有许多超过两个操作需要按特定顺序执行的更一般情况。这是由于 switch 表格的顺序需要根据限制变得更加复杂。对于这个简单的例子,我的解决方案可能更好,但 Rando 的解决方案是最佳实践。 - Matthew Ciaramitaro
这可能是最好的方法,我只是试图避免分割代码(操作并不够大或复杂)。 - Tara

3

解决方案

为了让两种情况都执行B操作,我们可以按顺序列出它们,不使用break语句,然后使用一个if语句代替你用来执行不需要的操作1的重复case语句。

switch(variable) {
    case 0:
    case 1:
        // operation B;
        if(variable === 0) //operation A ;
        break;
    
}

或者,如果B过程无论在什么情况下都需要在A过程之前进行,则嵌套函数将是一个很好的解决方案。

process_A = function(){
  process_B();
  console.log("running operation A");
  //operation A;
}
process_B = function(){
  console.log("running operation B");
  //operation B;
}
variable = 0;
switch(variable) {
    case 0:
        process_A();
        break;
    case 1:
        process_B();
        break;
        
}

开关表和重复案例的解释

在开关表中包含重复案例没有意义。变量只会索引到一个案例。如果您需要在条件之间建立复杂的关系,可能需要使用ifelse块或类似Rando解决方案的方法。

以下代码片段演示了为什么不应该在开关表中使用重复案例:

var variable = 0;
switch(variable) {
    case 0:
        console.log("case 0: No Op performed");
    case 1:
        // operation B;
        console.log("case 1: Op B performed");
        break;
    case 0:
        // operation A;
        console.log("case 0: Op A performed");
        break;
}

注意到操作A从未运行。
一个switch表类似于一个数组。每个case都是表的索引,这使我们可以快速处理条件,而不是线性地移动ifelse块。当我们索引一个switch表时,执行从该索引到表尾或第一个break的所有命令。

1
这将是首选答案。 - Dencio
@TaraStahler 我明白了,你想让情况0运行操作B和操作A,而情况1只运行操作B? - Matthew Ciaramitaro
是的,没错。但问题在于,需要先运行B案例。 - Tara
1
哈,是的...这不太优雅,但我担心在这种特殊情况下没有优雅的解决方案(if语句是多余的)^^ - Tara
好的,if语句并不是多余的,因为我们将case 0和case 1合并为一个单独的case,所以它只是在两者之间进行分离。但是,没有函数抽象可能没有优雅的解决方案。 - Matthew Ciaramitaro
显示剩余2条评论

0

很容易测试并发现它的工作方式不完全符合您的期望:

function doStuff(x) {
  console.log(`with ${x}:`);
  switch (x) {
    case 0:
    case 1:
      console.log("operation B");
      break;
    case 0:
      console.log("operation A");
      break;
  }
}
doStuff(0);
doStuff(1);

第二种情况 case 0 虽然在语法上是合法的,但代码永远不会到达这个分支。 在这些情况下,通常最好根据需要组合 case 标签,然后使用 if (甚至更多 switch )将其分配到不同的操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接