สลับคำสั่งหลายกรณีใน JavaScript


767

ฉันต้องการหลายกรณีในงบ switch ใน JavaScript สิ่งที่ชอบ:

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

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

ฉันจะทำสิ่งนั้นได้อย่างไร ถ้ามีวิธีที่จะทำสิ่งที่ต้องการที่ใน JavaScript ไม่ฉันต้องการที่จะรู้วิธีการแก้ปัญหาทางเลือกที่ยังตามแนวคิดแห้ง


5
ถึงคนที่โหวตให้ปิดคำถามนี้ มีอายุมากกว่า 5 ปีและมีคำตอบที่ถูกต้อง - ทำไมจึงโหวตอย่างใกล้ชิด?
surfmuggle

@surfmuggle เนื่องจากไม่จำเป็นต้องเพิ่มคำตอบเพิ่มเติม
Afshin Mehrabani

7
@AshshMeMeababani อาจจะสามารถป้องกันไม่ได้ปิด?
evolutionxbox

คำตอบ:


1508

ใช้คุณสมบัติ fall-through ของswitchคำสั่ง กรณีที่จับคู่จะทำงานจนกว่าจะพบbreak(หรือจุดสิ้นสุดของswitchคำสั่ง) ดังนั้นคุณสามารถเขียนได้เช่น:

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

   default: 
       alert('Default case');
}


2
ยังไงก็เถอะมันทำงานได้ดีสำหรับฉันใน Chrome ในคอนโซลจาวาสคริปต์: switch('10') { case 1, '10': console.log('ok') }พิมพ์ok
nafg

8
@nafg: switch(1)ลอง ป้ายกำกับที่นี่เป็นเพียงการแสดงออกด้วยเครื่องหมายจุลภาค
kennytm

4
@ บาร์นีย์ไม่โดยไม่ต้องหยุดคุณสามารถผ่านไปยังกรณีต่อไป
Seiyria

1
@Seiyira ตามคำนิยามไม่มีกรณีต่อไปหลังจากที่ผ่านมา นอกจากนี้มันเป็นค่าเริ่มต้น
บาร์นีย์

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 มันเป็นกรณีปกติธรรมดาที่ผิดพลาดกับการจัดรูปแบบแปลก ๆ (ช่องว่างแทนการขึ้นบรรทัดใหม่)
Mihail Malostanidis

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/12/switch-case-considered-harmful
Eric Elliott

31
ฉันมักจะเพิ่มความคิดเห็น//fallthroughในสถานที่ของทุกครั้งที่ผมจงใจละเว้นbreak breakที่ช่วยในการระบุเมื่อมันเป็นความผิดพลาดและเมื่อมันตั้งใจ
Mnebuerquo

18
วิธีการที่ใช้งานง่าย อย่างไรก็ตามเพื่อความสะดวกในการอ่านฉันแนะนำให้ใช้คำสั่งสวิตช์เนทีฟ
contactmatt

39
หนึ่งสามารถเกาหูซ้ายผ่านมือขวาผ่านด้านหลังคอ ... (ขอโทษสำหรับภาษาอังกฤษของฉันฉันหมายถึง: "ใคร ๆ ก็สามารถทำให้สิ่งต่าง ๆ ซับซ้อนเท่าที่จะทำได้ ... ในกรณีนี้หลีกเลี่ยงคำสั่งเปลี่ยน ในความโปรดปรานของวิธีการแก้ปัญหาที่ซับซ้อนนี้ดูเหมือนจะไม่ใช่สิ่งที่ถูกต้องที่จะทำ ... )
Clint Eastwood

25
ฉันประหลาดใจอย่างแท้จริงว่าสิ่งนี้ได้รับ 34 โหวต ในแง่ของการอ่านและการบำรุงรักษานี้เป็นที่น่ากลัวอย่างแน่นอน หากฉันต้องการดูว่าเงื่อนไขใดที่จะกระตุ้นให้เกิดสิ่งใดคำสั่งของคดีจะไม่น่าเชื่อและดูง่ายโดยดูที่ฉลาก ในทางกลับกันเวอร์ชันของคุณจะต้องมีคนอ่านมากทุกบรรทัดและดูสิ่งที่คุณได้รับมอบหมาย สิ่งนี้ยิ่งแย่ลงไปเรื่อย ๆ ในกรณีที่คุณต้องการจับคู่
ไมเคิล

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
เป็นเทคนิคทั่วไปใน pletora ของภาษาไม่ผูกกับ JS
drAlberT

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 รุ่นเก่า แต่คุณสามารถแก้ไขสิ่งต่าง ๆ ได้อย่างง่ายดาย ดูคำถามว่าสตริงอยู่ในรายการในจาวาสคริปต์สำหรับข้อมูลเพิ่มเติมหรือไม่


อะไรคือประโยชน์ของสวิตช์นี้?
ไบรซ์สไนเดอ

@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

1
@AshshMeMeababani อาจเป็นไปได้ว่าฉันได้ทดสอบเฉพาะในบริบทของ nodejs
Automatico

ใช่. ฉันชอบประหยัดพื้นที่แนวตั้ง!
ช่อง

7

การเพิ่มและทำให้คำตอบของสเตฟาโนชัดเจนขึ้นคุณสามารถใช้นิพจน์เพื่อกำหนดค่าสำหรับเงื่อนไขในสวิทช์เช่น:

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ภายในนิพจน์ของเคสคาดว่า varName จะถูกแคชไว้
Valen

5

คุณสามารถใช้โอเปอเรเตอร์ ' in ' ...
ขึ้นอยู่กับการร้องขอ object / hash ...
ดังนั้นจึงเร็วเท่า 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

สวัสดี Matt ... ฉันกำลังนำเสนอที่นี่เพื่อพิสูจน์แนวคิด ... อย่างไรก็ตามแบบฟอร์มนี้ให้ความสนุกสนานและความยืดหยุ่นมากกว่าเดิม ... และคุณใช้มันเฉพาะเมื่อคุณต้องการ ... หรือหากคุณพบข้อ จำกัด ในตัวคุณ รูปแบบปกติของการทำสิ่ง ... พิจารณา ir เป็นเครื่องมือหนึ่งที่เพิ่มเติมในกล่องเครื่องมือของโปรแกรมเมอร์ของคุณ ...
ZEE

5

ฉันใช้สิ่งนี้:

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

คุณไม่จำเป็นต้องใช้gธงเนื่องจากคุณใช้ regexes เพียงครั้งเดียวและทิ้งมันไป ในความเป็นจริงหากคุณเก็บไว้นอกฟังก์ชันการgตั้งค่าสถานะจะเป็นอันตรายต่อคุณโดยพยายามจับคู่จากดัชนีที่ไม่ใช่ 0 ใน.test(s ต่อมา ฉันยังคงพิมพ์ผิดที่กรณีสวิตช์อยู่ในsensorตัวแปรและไม่trueคงที่สำหรับการจับคู่การแสดงออกบูลีน ดูการแก้ไข
Mihail Malostanidis

ฉันใช้รูปแบบนี้เพื่อทดสอบกับประเภทไฟล์ ตัวอย่าง:case /officedocument/.test(type) && /presentation/.test(type): iconClass = "far fa-file-powerpoint red"; break;
tbone849

4

มันขึ้นอยู่กับ. Switchประเมินค่าเพียงครั้งเดียว ในการแข่งขันแถลงการณ์ที่ตามมาทั้งหมดจะเริ่มต้นจนกว่าจะ 'ไฟไหม้' ไม่ว่าคดีจะเป็นเช่นไร

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
นี่เป็นการละเมิดคำสั่งเปลี่ยน แค่if (accessDenied.includes(varName)) return 'Access Denied!'; return 'Access Allowed.'มากเกินพอ
Mihail Malostanidis

2

ปัญหาด้วยวิธีการดังกล่าวข้างต้นคือการที่คุณจะต้องทำซ้ำหลายcases 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 (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 reducers


0

หนึ่งในวิธีแก้ปัญหาที่เป็นไปได้คือ:

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

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

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

Q กรุณา #ecma นี่คืออะไร?
BG Bruno

สวัสดี. นี่คือ 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

ทำไมไม่ใส่ค่าวันในกรณีและdocument.getElementById("result").innerHTML = ....นอกสวิตช์และเพิ่มผลลัพธ์ค่าวันที่สิ้นสุด
Steffo Dimfelt

@ Xufox ฉันชอบที่เขาเขียนทับตัวอักษรอย่างแท้จริงnumแต่ก็ยังใช้งานได้เพราะswitchได้รับการประเมินแล้วและการมอบหมายนั้นให้คุณค่า นี่คือการเขียนโปรแกรมโดยการกลายพันธุ์ / การเรียนรู้เครื่องที่ดีที่สุด
Mihail Malostanidis

-3

เพียงแค่สลับเงื่อนไข aprroach

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

2
หากคุณใส่ความจริงเป็นนิพจน์สวิตช์ในคำสั่ง "case" คุณสามารถประเมินสิ่งที่คุณต้องการหากคุณส่งคืนบูลีน
Stefano Favero

1
ฉันคิดว่าสิ่งที่เขาหมายถึงคือคุณสามารถใส่นิพจน์ภายในฟังก์ชันซึ่งจะประเมินและส่งกลับค่าไดนามิกสำหรับกรณีดังนั้นจึงอนุญาตให้มีเงื่อนไขที่ซับซ้อนได้ทุกประเภท
Z. Khullah

สำหรับ @StefanoFavero โปรดทราบว่าคุณไม่จำเป็นต้องมีฟังก์ชั่นเพียงแค่(expression)อยู่ในวงเล็บและค่าส่งคืนจะต้องเป็นอินพุต ดูคำตอบของฉัน
Z. Khullah

ทำไมคุณถึงย่อมัน ฉันสนับสนุนโซลูชันนี้เพราะให้ความยืดหยุ่นสำหรับเงื่อนไขที่ซับซ้อน แม้ว่าคุณไม่ชอบ funcs เป็นเงื่อนไขคุณอาจแทนที่พวกเขาด้วยคุณหลายเงื่อนไขเช่นswitch(true) { case (var1 === 0 && var2 === true): {} }
AlexNikonov
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.