@@ -1,22 +1,22 @@ # คำสั่ง "switch" คำสั่ง `switch`สามารถใช้แทนการตรวจสอบ `if` หลายๆ ครั้งได้ คำสั่ง `switch`สามารถใช้แทนการตรวจสอบด้วย `if` หลายๆ ครั้งได้ มันให้วิธีที่อธิบายได้ชัดเจนกว่าในการเปรียบเทียบค่าหนึ่งกับหลายๆ กรณี มันให้วิธีเปรียบเทียบค่ากับตัวเลือกหลายๆ ตัวอย่างเข้าใจง่ายกว่า ##รูปแบบ ##ไวยากรณ์ คำสั่ง `switch`มีหนึ่งหรือหลาย `case`บล็อก และตัวเลือก `default``switch`จะมีหนึ่งหรือหลายบล็อก `case`และมี `default` เป็นตัวเลือกเสริม มีรูปแบบดังนี้: ```js no-beautify switch(x) { case 'ค่า1 ': // ถ้า (x === 'ค่า1 ') case 'value1 ': // ถ้า (x === 'value1 ') ... [break] case 'ค่า2 ': // ถ้า (x === 'ค่า2 ') case 'value2 ': // ถ้า (x === 'value2 ') ... [break] Expand All @@ -26,39 +26,39 @@ switch(x) { } ``` -ค่า `x`จะถูกตรวจสอบความเท่ากันอย่างเข้มงวด (strict equality) กับค่าจาก `case` แรก (คือ `ค่า1 `)จากนั้นกับ `case` ที่สอง (`ค่า2 `) และต่อไปเรื่อยๆ -ถ้าพบว่าเท่ากัน `switch`จะเริ่มทำงานโค้ดจาก `case`ที่ตรงกันนั้น ไปจนถึง `break` ที่ใกล้ที่สุด (หรือจนจบ `switch`) -ถ้าไม่มี case ใดตรงกัน จะรันโค้ดใน `default` (ถ้ามี) -ค่าของ `x`จะถูกตรวจสอบความเท่าเทียมกันอย่างเข้มงวดกับค่าจาก `case` แรก (คือ `value1 `)จากนั้นเป็น `case` ที่สอง (`value2 `) และต่อไปเรื่อยๆ -ถ้าพบความเท่ากัน `switch`จะเริ่มรันโค้ดจาก `case`ที่ตรงกัน จนกว่าจะเจอ `break` ที่ใกล้ที่สุด (หรือจนจบ `switch`) -ถ้าไม่ตรงกับ ` case` ใด โค้ดใน `default` จะถูกรัน (ถ้ามี) ## ตัวอย่าง ตัวอย่างของ `switch` (ส่วนที่ถูกรันจะเน้นสีไว้ ): ตัวอย่างของ `switch` (โค้ดที่ถูกรันจะเน้นให้เห็น ): ```js run let a = 2 + 2; switch (a) { case 3: alert( 'เล็กเกินไป ' ); alert( 'เล็กไป ' ); break; *!* case 4: alert( 'ถูกต้องแล้ว !' ); alert( 'ถูกต้อง !' ); break; */!* case 5: alert( 'ใหญ่เกินไป ' ); alert( 'ใหญ่ไป ' ); break; default: alert( "ไม่รู้จักค่าแบบนี้ " ); alert( "ไม่รู้จักค่านี้ " ); } ``` ในที่นี้ `switch` จะเริ่มเปรียบเทียบ `a` กับvariant `case`แรก คือ `3` ซึ่งไม่ตรงกันที่นี่ `switch` จะเริ่มเปรียบเทียบ `a` กับ `case`แรกคือ `3` ซึ่งไม่ตรงกันจากนั้นกับ `4` ซึ่งตรงกันเพราะฉะนั้นการทำงานจะเริ่มจาก `case 4`ไปจนถึง `break` ที่ใกล้ที่สุด จากนั้นเป็น `4` ซึ่งตรงกันดังนั้นโค้ดจะเริ่มรันจาก `case 4`จนกว่าจะเจอ `break`**ถ้าไม่มี `break`การทำงานจะดำเนินต่อไปยัง `case`ถัดไปโดยไม่มีการตรวจสอบใดๆ** **ถ้าไม่มี `break`โค้ดจะรันต่อไปยัง `case`ถัดไปเลยโดยไม่ตรวจสอบอะไร** ตัวอย่างที่ไม่มี `break`: Expand All @@ -67,30 +67,30 @@ let a = 2 + 2; switch (a) { case 3: alert( 'เล็กเกินไป ' ); alert( 'เล็กไป ' ); *!* case 4: alert( 'ถูกต้องแล้ว !' ); alert( 'ถูกต้อง !' ); case 5: alert( 'ใหญ่เกินไป ' ); default: alert( "ไม่รู้จักค่าแบบนี้ " ); alert( 'ใหญ่ไป ' ); default: alert( "ไม่รู้จักค่านี้ " ); */!* } ``` ในตัวอย่างด้านบน เราจะเห็นการทำงานต่อเนื่องกันของ `alert`สามครั้ง :ในตัวอย่างข้างบน จะเห็น `alert`สามอันทำงานต่อเนื่องกัน :```js alert( 'ถูกต้องแล้ว !' ); alert( 'ใหญ่เกินไป ' ); alert( "ไม่รู้จักค่าแบบนี้ " ); alert( 'ถูกต้อง !' ); alert( 'ใหญ่ไป ' ); alert( "ไม่รู้จักค่านี้ " ); ``` ````smart header="นิพจน์ใดๆ สามารถใช้เป็น argument ของ `switch/case` ได้" ทั้ง `switch` และ `case`ยอมให้ใช้นิพจน์แบบใดก็ได้ ````smart header="นิพจน์อะไรก็ใช้เป็นอาร์กิวเมนต์ของ `switch/case` ได้" ทั้ง `switch` และ `case`สามารถใช้นิพจน์อะไรก็ได้ ตัวอย่างเช่น :เช่น :```js run let a = "1"; Expand All @@ -99,22 +99,22 @@ let b = 0; switch (+a) { *!* case b + 1: alert("นี่รัน เพราะ +a เป็น 1 ซึ่งเท่ากับ b+1 พอดี "); alert("นี่ทำงาน เพราะ +a เป็น 1 ซึ่งเท่ากับ b+1"); break; */!* default: alert("นี่ไม่รัน "); alert("นี่ไม่ทำงาน "); } ``` ที่นี่ `+a` ให้ค่า `1`ซึ่งเปรียบเทียบกับ `b + 1` ใน `case`และโค้ดที่สอดคล้องกันจะทำงาน ที่นี่ `+a` ให้ค่า `1`ซึ่งจะถูกเปรียบเทียบกับ `b + 1` ใน `case`และโค้ดที่สอดคล้องจะถูกรัน ```` ##การจัดกลุ่มของ "case" ##การจัดกลุ่ม "case" หลาย variant ของ `case`ที่ใช้โค้ดเดียวกันสามารถจัดกลุ่มเข้าด้วยกันได้ `case`หลายๆ แบบที่รันโค้ดเดียวกัน สามารถจัดกลุ่มรวมกันได้ ตัวอย่างเช่นถ้าเราต้องการให้โค้ดเดียวกันรันสำหรับทั้ง `case 3` และ `case 5`: ตัวอย่างเช่นถ้าเราต้องการให้โค้ดเดียวกันทำงานทั้งใน `case 3` และ `case 5`: ```js run no-beautify let a = 3; Expand All @@ -125,25 +125,25 @@ switch (a) { break; *!* case 3: // (*) จัดกลุ่มสอง case case 3: // (*) จัดกลุ่มสอง case ไว้ด้วยกัน case 5: alert('ผิด!'); alert("ทำไมคุณไม่ไปเรียนคณิตศาสตร์ดูล่ะ? "); alert("ลองไปเรียนคณิตหน่อยไหม "); break; */!* default: alert('ผลลัพธ์แปลกๆ นะ '); alert('ผลลัพธ์แปลกมากเลย '); } ``` ตอนนี้ทั้ง `3` และ `5`ก็จะแสดงข้อความเดียวกัน ตอนนี้ทั้ง `3` และ `5`จะแสดงข้อความเดียวกัน ความสามารถในการ "จัดกลุ่ม" case เป็นผลข้างเคียงของวิธีการทำงานของ `switch/case`โดยไม่มี `break`ที่นี่การทำงานของ `case 3`เริ่มจากบรรทัด `(*)`และไปต่อยัง `case 5` เพราะไม่มี `break` ความสามารถในการ "จัดกลุ่ม"` case` เป็นผลข้างเคียงของวิธีการทำงานของ `switch/case`เมื่อไม่มี `break`ในที่นี้ `case 3`จะเริ่มรันโค้ดจากบรรทัด `(*)`และรันผ่าน `case 5`ไปเลย เพราะไม่มี `break` ## ชนิดข้อมูลมีความสำคัญ ขอเน้นว่าการตรวจสอบความเท่ากันจะเป็นแบบเข้มงวด (strict equality) เสมอ ค่าต้องมีชนิดเดียวกันจึงจะตรงกัน ขอเน้นว่าการตรวจสอบความเท่ากันจะเป็นแบบเข้มงวดเสมอ ค่าต้องเป็นชนิดเดียวกันจึงจะตรงกัน ตัวอย่างเช่น ลองพิจารณาโค้ดนี้: Expand All @@ -160,13 +160,13 @@ switch (arg) { break; case 3: alert( 'ไม่มีทางรัน !' ); alert( 'จะไม่มีทางรันเลย !' ); break; default: alert( 'ค่าที่ไม่รู้จัก' ); } ``` 1. สำหรับ `0`, `1`, `alert`แรกจะทำงาน 2. สำหรับ `2`, `alert`ที่สองจะทำงาน 3. แต่สำหรับ `3`, ผลลัพธ์ของ `prompt`คือสตริง `"3"`, ซึ่งไม่เท่ากับ `===`ตัวเลข `3`ดังนั้นเราจึงมีโค้ดที่ไม่มีทางรันใน `case 3`!ส่วน `default`จะทำงานแทน 1. สำหรับ `0`, `1` จะแสดง `alert`แรก 2. สำหรับ `2` จะแสดง `alert`ที่สอง 3. แต่สำหรับ `3` ผลลัพธ์จาก `prompt`จะเป็น string `"3"` ซึ่งไม่เท่ากันอย่างเข้มงวด `===`กับตัวเลข `3`ดังนั้นเราจะมีโค้ดที่ไม่มีทางรันได้ใน `case 3`!แต่ `default`จะถูกรันแทน