在JavaScript中切换语句多个案例


764

我需要在JavaScript的switch语句中使用多种情况,例如:

switch (varName)
{
   case "afshin", "saeed", "larry": 
       alert('Hey');
       break;

   default: 
       alert('Default case');
       break;
}

我怎样才能做到这一点?如果没有办法在JavaScript中执行类似的操作,我想知道一个也遵循DRY概念的替代解决方案。


5
投票赞成关闭这个问题的人。它已经有5年以上的历史了,并且有一个有力的回答-为什么要进行密切投票?
surfmuggle 18/02/21

@surfmuggle,因为没有必要添加更多答案。
Afshin Mehrabani

7
@AfshinMehrabani也许可以受到保护,而不是封闭?
Evolutionxbox

Answers:


1504

使用switch语句的直通功能。匹配的大小写将一直运行到找到break(或switch语句的末尾)为止,因此您可以这样写:

switch (varName)
{
   case "afshin":
   case "saeed":
   case "larry": 
       alert('Hey');
       break;

   default: 
       alert('Default case');
}


2
在Chrome中的javascript控制台中,它以某种方式对我switch('10') { case 1, '10': console.log('ok') }ok
有用

8
@nafg:尝试switch(1)。这里的标签只是一个逗号表达式。
kennytm

4
@Barney不,没有休息,您可以继续进行下一个案例。
Seiyria

1
@Seiyira根据定义,在最后一个之后没有下一个情况。此外,这是默认设置。
巴尼2015年

101

这适用于常规JavaScript

function theTest(val) {
  var answer = "";
  switch( val ) {
    case 1: case 2: case 3:
      answer = "Low";
      break;
    case 4: case 5: case 6:
      answer = "Mid";
      break;
    case 7: case 8: case 9:
      answer = "High";
      break;
    default:
      answer = "Massive or Tiny?";
  } 
  return answer;  
}

theTest(9);

干杯。


13
@believesInSanta字面意思是正常情况下使用奇怪的格式(空格而不是换行符)
掉线

42

这是一种switch完全避免该语句的不同方法:

var cases = {
  afshin: function() { alert('hey'); },
  _default: function() { alert('default'); }
};
cases.larry = cases.saeed = cases.afshin;

cases[ varName ] ? cases[ varName ]() : cases._default();

5
我绝对喜欢这个版本。掉线是的易错功能switch ... case。忘记一条break语句太容易了,如果您故意使用掉线,那么那些被遗忘的break语句可能很难发现。此方法查找版本还具有许多switch ... case缺少的重要功能,例如动态可扩展性或完全替换对象以完成模式切换的功能。保持整洁的组织也更容易,并且可以导致更易于维护的代码。参见ericleads.com/2012/12/switch-case-considered-harmful
Eric Elliott

31
我总是添加注释//fallthrough的地方break,每当我故意省略了break。这有助于确定什么时候是错误的,什么时候是故意的。
Mnebuerquo 2014年

18
直观的方法。但是,出于可读性考虑,我建议使用本机switch语句。
contactmatt 2014年

39
一个人总是可以刮擦左耳,将右手穿过脖子的后部……(对不起,我的意思是:“一个人总是可以尽可能地使事情复杂化……在这种情况下,避免使用switch语句支持这种复杂的解决方案似乎不是正确的事情……)
Clint Eastwood 2014年

25
我真的很惊讶这如何获得34票。在可读性和可维护性方面,这绝对是可怕的。如果我想看看什么情况会触发某些事情,那么通过查看标签就可以很容易地找到一个case语句。另一方面,您的版本将要求某人几乎每行都阅读一遍,并查看您在何处分配了什么。您想要匹配的案例越多,情况就越糟。
迈克尔,

21

在Javascript中分配一个开关中的多种情况时,我们必须定义different case without break inbetween如下所示:

   <script>
      function checkHere(varName){
        switch (varName)
           {
           case "saeed":
           case "larry":
           case "afshin":
                alert('Hey');
                break;
          case "ss":
               alert('ss');
               break;
         default:
               alert('Default case');
               break;
       }
      }
     </script>

请看示例点击链接


5
这是大量语言中的一种常用技术,不
局限于

13

如果您使用的是ES6,则可以执行以下操作:

if (['afshin', 'saeed', 'larry'].includes(varName)) {
   alert('Hey');
} else {
   alert('Default case');
}

或者对于早期版本的JavaScript,您可以执行以下操作:

if (['afshin', 'saeed', 'larry'].indexOf(varName) !== -1) {
   alert('Hey');
} else {
   alert('Default case');
}

请注意,这在较旧的IE浏览器中不起作用,但是您可以相当轻松地对其进行修补。有关更多信息,请参见确定字符串是否在javascript列表中的问题。


这比开关有什么好处?
布莱斯·斯奈德

@BryceSnyder表达式和语句之间的区别?打字少吗?消耗的垂直线更少?通过简洁和代表密度来增强表达能力?通过includes单词更好的语义?随便你吧。
ErikE

7

在节点中,似乎可以执行此操作:

data = "10";
switch(data){
case "1": case "2": case "3": //put multiple cases on the same line to save vertical space.
   console.log("small"); break;
case "10": case "11": case "12":
   console.log("large"); break;
default:
   console.log("strange");
   break;
}

在某些情况下,这使代码更紧凑。


1
我认为语法与其他JS环境相同。
Afshin Mehrabani 2015年

1
@AfshinMehrabani可能是,我仅在nodejs上下文中对其进行了测试。
Automatico

是。我喜欢节省垂直空间!
频道

7

添加并阐明Stefano的答案后,您可以使用表达式来动态设置switch中条件的值,例如:

var i = 3
switch (i) {
    case ((i>=0 && i<=5)?i:-1): console.log('0-5'); break;
    case 6: console.log('6');
}

因此,在遇到问题时,您可以执行以下操作:

var varName = "afshin"
switch (varName) {
    case (["afshin", "saeed", "larry"].indexOf(varName)+1 && varName):
      console.log("hey");
      break;

    default:
      console.log('Default case');
}

虽然没有那么干


尚未测试,但varName在case表达式内部进行修改将很有趣,因为您希望将varName缓存起来。
瓦伦

5

您可以使用' in '运算符...
取决于对象/哈希调用...
因此它的速度与javascript一样快...

// assuming you have defined functions f(), g(a) and h(a,b) 
// somewhere in your code
// you can define them inside the object but... 
// the code becomes hard to read, I prefer this way

o = { f1:f, f2:g, f3:h };

// if you use "STATIC" code can do:
o['f3']( p1, p2 )

// if your code is someway "DYNAMIC", to prevent false invocations
// m brings the function/method to be invoked (f1, f2, f3)
// and you can rely on arguments[] to solve any parameter problems
if ( m in o ) o[m]()

享受,ZEE


这与开关有何关系?你能澄清一下吗?
Z. Khullah

为什么要使代码“难以阅读”。作为程序员,我被告知的第一件事是以一种思维方式来编写代码,即下一个阅读您的代码的人是持串行杀手的斧头,他讨厌不懂代码。
MattE '18

嗨,马特...我在这里展示它是一种概念证明...无论如何,这种形式为您提供了更多的功能性和灵活性...并且只有在您需要时才使用它...或者如果您发现自己的限制条件通常的做事方式...在您的程序员工具箱中将ir视为另一种工具...
ZEE

5

我这样使用:

switch (true){
     case /Pressure/.test(sensor):{
        console.log('Its pressure!');
        break;
     }
     case /Temperature/.test(sensor):{
        console.log('Its temperature!');
        break;
     }
}

您不需要使用该g标志,因为您只使用了一次正则表达式并将其丢弃。实际上,如果将它们保留在函数之外,则该g标志将通过尝试从后续.test(s 上的非0索引进行匹配而对您造成伤害。我还修复了一个错字,即开关大小写在sensor变量上,而不是true常量,无法匹配布尔表达式。参见编辑。
Mihail Malostanidis

我使用这种格式来测试文件类型。例如:case /officedocument/.test(type) && /presentation/.test(type): iconClass = "far fa-file-powerpoint red"; break;
tbone849

4

这取决于。 开关仅计算一次。比赛结束后,无论案件内容如何,​​所有随后的案件陈述(直至“中断”)均会触发。

var onlyMen = true;
var onlyWomen = false;
var onlyAdults = false;
 
 (function(){
   switch (true){
     case onlyMen:
       console.log ('onlymen');
     case onlyWomen:
       console.log ('onlyWomen');
     case onlyAdults:
       console.log ('onlyAdults');
       break;
     default:
       console.log('default');
   }
})(); // returns onlymen onlywomen onlyadults
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>


3

为了清晰和DRY语法,我喜欢这样做。

varName = "larry";

switch (true)
{
    case ["afshin", "saeed", "larry"].includes(varName) :
       alert('Hey');
       break;

    default: 
       alert('Default case');

}

2

我可以看到这里有很多好的答案,但是如果我们需要检查10个以上的案例,会发生什么?这是我自己的方法:

 function isAccessible(varName){
     let accessDenied = ['Liam','Noah','William','James','Logan','Benjamin',
                        'Mason','Elijah','Oliver','Jacob','Daniel','Lucas'];
      switch (varName) {
         case (accessDenied.includes(varName)?varName:null): 
             return 'Access Denied!';
         default:
           return 'Access Allowed.';
       }
    }

    console.log(isAccessible('Liam'));

1
这是对switch语句的滥用。仅仅if (accessDenied.includes(varName)) return 'Access Denied!'; return 'Access Allowed.'是绰绰有余。
Mihail Malostanidis

2

上述方法的问题在于,case每次调用具有的函数时,都必须重复几个switch。一个更可靠的解决方案是拥有地图字典

这是一个例子

// the Map, divided by concepts
var dictionary = {
  timePeriod: {
    'month': [1, 'monthly', 'mensal', 'mês'],
    'twoMonths': [2, 'two months', '2 motnhs', 'bimestral', 'bimestre'],
    'trimester': [3, 'trimesterly', 'quarterly', 'trimestral'],
    'semester': [4, 'semesterly', 'semestral', 'halfyearly'],
    'year': [5, 'yearly', 'anual', 'ano']
  },
  distance: {
    'km': [1, 'kms', 'kilometre', 'kilometers', 'kilometres'],
    'mile': [2, 'mi', 'miles'],
    'nordicMile': [3, 'nordic mile', 'mil(10km)', 'scandinavian mile']
  },
  fuelAmount: {
    'ltr': [1, 'l', 'litre', 'Litre', 'liter', 'Liter'],
    'gal(imp)': [2, 'imp gallon', 'imperial gal', 'gal(UK)'],
    'gal(US)': [3, 'US gallon', 'US gal'],
    'kWh': [4, 'KWH']
  }
};

//this function maps every input to a certain defined value
function mapUnit (concept, value) {
  for (var key in dictionary[concept]) {
    if (key === value || 
      dictionary[concept][key].indexOf(value) !== -1) {
      return key
    }
  }
  throw Error('Uknown "'+value+'" for "'+concept+'"')
}

//you would use it simply like this
mapUnit("fuelAmount", "ltr") // => ltr
mapUnit("fuelAmount", "US gal") // => gal(US)
mapUnit("fuelAmount", 3) // => gal(US)
mapUnit("distance", "kilometre") // => km
  
//now you can use the switch statement safely without the need 
//to repeat the combinations every time you call the switch
var foo = 'monthly'
switch (mapUnit ('timePeriod', foo)) {
  case 'month': 
    console.log('month')
    break
  case 'twoMonths': 
    console.log('twoMonths')
    break
  case 'trimester': 
    console.log('trimester')
    break
  case 'semester': 
    console.log('semester')
    break
  case 'year': 
    console.log('year')
    break
  default:
    throw Error('error')
}


1

你可以这样做:

alert([
  "afshin", 
  "saeed", 
  "larry",
  "sasha",
  "boby",
  "jhon",
  "anna",
  // ...
].includes(varName)? 'Hey' : 'Default case')

或仅一行代码:

alert(["afshin", "saeed", "larry",...].includes(varName)? 'Hey' : 'Default case')

ErikE的回答有一点改进


1

对于来到这里遇到类似问题的人,经过数周的编码和倦怠,我遇到了类似的问题,我的情况类似于:

switch (text) {
  case SOME_CONSTANT || ANOTHER_CONSTANT:
    console.log('Case 1 entered');

  break;

  case THIRD_CONSTANT || FINAL_CONSTANT:
    console.log('Case 2 entered');

  break;

  default:
    console.log('Default entered');
}

总是输入default大小写。如果您遇到类似的多案例switch语句问题,那么您正在寻找的是:

switch (text) {
  case SOME_CONSTANT:
  case ANOTHER_CONSTANT:
    console.log('Case 1 entered');

  break;

  case THIRD_CONSTANT:
  case FINAL_CONSTANT:
    console.log('Case 2 entered');

  break;

  default:
    console.log('Default entered');
}

希望这对某人有帮助,在想起使用开关盒的方式之前,我想把头发拉出来,就像在redux减速器中一样。


0

可能的解决方案之一是:

const names = {
afshin: 'afshin',
saeed: 'saeed',
larry: 'larry'
};

switch (varName) {
   case names[varName]: {
       alert('Hey');
       break;
   }

   default: {
       alert('Default case');
       break;
   }
}

问请问这是哪个#ecma?
BG布鲁诺

嗨,您好。这是ES6
Jackkobec

0

对我来说,这是最简单的方法:

switch (["afshin","saeed","larry"].includes(varName) ? 1 : 2) {
   case 1: 
       alert('Hey');
       break;

   default: 
       alert('Default case');
       break;
}

-1

在函数内部时,在switch语句中处理多种情况的另一种方法

function name(varName){
  switch (varName) {
     case 'afshin':
     case 'saeed':
     case 'larry':
       return 'Hey';
     default:
       return 'Default case';
   }
}
        
console.log(name('afshin')); //Hey


-2

您可以这样写:

switch (varName)
{
   case "afshin": 
   case "saeed": 
   case "larry": 
       alert('Hey');
       break;

   default: 
       alert('Default case');
       break;
}         

6
这是与其他所有人相同的答案,我将修复您忘记的“,但请考虑删除它。”
Gaunt

-3
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Example1</title>
    <link rel="stylesheet" href="css/style.css" >
    <script src="js/jquery-1.11.3.min.js" type="text/javascript"></script>
    <script>
        function display_case(){
            var num =   document.getElementById('number').value;

                switch(num){

                    case (num = "1"):
                    document.getElementById("result").innerHTML = "You select day Sunday";
                    break;

                    case (num = "2"):
                    document.getElementById("result").innerHTML = "You select day  Monday";
                    break;

                    case (num = "3"):
                    document.getElementById("result").innerHTML = "You select day  Tuesday";
                    break;

                    case (num = "4"):
                    document.getElementById("result").innerHTML = "You select day  Wednesday";
                    break;

                    case (num = "5"):
                    document.getElementById("result").innerHTML = "You select day  Thusday";
                    break;

                    case (num = "6"):
                    document.getElementById("result").innerHTML = "You select day  Friday";
                    break;

                    case (num = "7"):
                    document.getElementById("result").innerHTML = "You select day  Saturday";
                    break;

                    default:
                    document.getElementById("result").innerHTML = "You select day  Invalid Weekday";
                    break
                }

        }
    </script>
</head>
<body>
    <center>
        <div id="error"></div>
        <center>
            <h2> Switch Case Example </h2>
            <p>Enter a Number Between 1 to 7</p>
            <input type="text" id="number" />
            <button onclick="display_case();">Check</button><br />
            <div id="result"><b></b></div>
        </center>
    </center>
</body>

3
经典jquery包含:)
ptim

4
这不是该switch语句应如何工作的方式。只是case "1":,不是case (num = "1"):
user4642212'1

为什么不将日值放入机箱内和document.getElementById("result").innerHTML = ....开关外部,并在末尾添加日值结果?
Steffo Dimfelt

@Xufox我很喜欢他的字面覆盖方式,num但是它仍然有效,因为switch已经进行了评估并且赋值产生了值。最好是通过变异/机器学习进行编程。
Mihail Malostanidis

-3

只需切换开关条件

switch (true) {
    case (function(){ return true; })():
        alert('true');
        break;
    case (function(){ return false; })():
        alert('false');
        break;
    default:
        alert('default');
}

2
如果将true表示为switch表达式,则在“ case”语句中,只要返回布尔值,就可以评估所需的值
Stefano Favero

1
我认为他的意思是您可以在函数内部放置一个表达式,该表达式将为情况求值并返回动态值,从而允许各种复杂的条件
Z. Khullah

对于此@StefanoFavero注释,您实际上不需要(expression)括号中的函数,并且返回值必须是输入。见我的回答
Z. Khullah

你为什么要减去它?我提倡这种解决方案,因为它为复杂条件提供了灵活性。即使您不喜欢使用func作为条件,也可以用多种条件替换它们,例如switch(true) { case (var1 === 0 && var2 === true): {} }
AlexNikonov
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.