Switch בוחר ענף אחד מתוך רבים
switch הוא משפט בקרת זרימה למצבים שבהם משווים ערך יחיד לקומץ אפשרויות ידועות. שרשרת של if/else if/else יכולה לעשות את אותה עבודה, אבל ברגע שבודקים את אותו משתנה שלוש או ארבע פעמים ברצף, switch קריא יותר.
הצורה הבסיסית:
אם קוראים את זה מלמעלה למטה: JavaScript מחשבת את day, משווה אותו לכל תווית case ומריצה את הבלוק שמתאים. default תופס כל מה שלא התאים, כמו else אחרון. סדר הקריאה הוא ערך ← case ← קוד.
איך ההתאמה עובדת בפועל
switch משווה באמצעות שוויון קפדני, כלומר האופרטור ===. בלי המרת טיפוסים, בלי התאמות מקורבות. case 1: יתאים למספר 1 אבל לא למחרוזת "1".
רק ה-case השני מתאים. אם אתם אי פעם מופתעים שה-switch שלכם לא מופעל, האשם הרגיל הוא אי התאמה בין מחרוזת למספר, שמגיעה משדה בטופס או מפרמטר ב-URL.
break הוא מה שעוצר את הזרימה
זה החלק שמכשיל אנשים. תווית case היא יעד קפיצה, לא בלוק עצמאי. ברגע שהביצוע נוחת על case מתאים, הוא ממשיך לרוץ שורה אחרי שורה, ישר דרך התווית של ה-case הבא, עד שהוא פוגש break, return או את סוף ה-switch.
שימו לב מה קורה בלי break:
ההתאמה היא "editor", אבל עדיין מקבלים יכול לערוך, יכול לצפות ו-מחובר. זה fallthrough: הביצוע נפל דרך כל אחד מה-cases הבאים כי שום דבר לא אמר לו לעצור.
הוסיפו break והוא מתנהג כמו שצריך:
הרגל טוב: כל case מסתיים ב-break, אלא אם אתם רוצים fallthrough במפורש.
Fallthrough מכוון לקיבוץ
Fallthrough הוא לא תמיד טעות. השמטת break היא דרך נקייה לומר "כל ה-cases האלה עושים את אותו הדבר":
תוויות case ריקות שמוערמות זו על זו חולקות את הבלוק שמתחתיהן. שימו לב שאין צורך ב-break אחרי return, כי הפונקציה יוצאת לגמרי. return בתוך switch מדלג על כל מה שהיה אמור לבוא אחריו.
כשאתם כן רוצים fallthrough בין cases שאינם ריקים, השאירו הערה כדי שהקורא הבא לא "יתקן" את זה:
default לא חייב לבוא אחרון
לפי המוסכמה default נמצא בתחתית, ושם רוב הקוראים מצפים למצוא אותו. אבל מבחינה טכנית הוא סתם עוד תווית: הוא מתאים כשאף case לא התאים, לא משנה איפה הוא נמצא. אם שמים default באמצע בלי break, הוא ייפול לתוך מה שנמצא מתחתיו. שימו אותו אחרון, סיימו אותו ב-break (או לא, כי שום דבר לא בא אחריו), והעצמי העתידי שלכם יודה לכם.
Scope של משתנים בתוך case
כל ה-cases חולקים scope אחד של בלוק: ה-switch כולו. הצהרה על let או const עם אותו שם בשני cases זורקת שגיאת הצהרה כפולה:
switch (x) {
case 1:
let msg = "one";
break;
case 2:
let msg = "two"; // SyntaxError: Identifier 'msg' has already been declared
break;
}
הפתרון הוא בלוק לכל case: עטפו את הגוף ב-{ }:
עכשיו כל msg חי ב-scope משלו וההתנגשות נעלמת. שווה לזכור את זה בכל פעם ש-case צריך יותר משורה או שתיים של לוגיקה.
switch מול if/else
switch מצטיין כשבודקים ערך אחד מול הרבה אפשרויות קבועות: קודי HTTP, סוגי actions של Redux, שמות פקודות, מחרוזות שמתנהגות כמו enum. הערך מופיע פעם אחת למעלה, והעין של הקורא יכולה לסרוק את תוויות ה-case כמו תוכן עניינים.
if/else עדיף כאשר:
- משווים טווחים (
score >= 90,score >= 75). - התנאים כוללים משתנים שונים או ביטויים בוליאניים.
- רוצים שוויון רופף או השוואות מותאמות אישית (
switchהוא תמיד===).
חלופה מודרנית נפוצה לדפוס הראשון היא חיפוש באובייקט:
שלוש שורות במקום switch של תשע שורות. כשה-cases הם מיפויים של נתונים בלבד בלי לוגיקה אמיתית, אובייקט (או Map) בדרך כלל קריא יותר. לכו על switch כשכל case עושה עבודה של ממש.
הבא בתור: לולאות for
switch מטפל בהחלטה אחת מול הרבה אפשרויות. החלק הבא של בקרת הזרימה הוא חזרה: הרצת אותו בלוק קוד שוב ושוב. בשביל זה יש לולאות for, שמגיעות מיד.
שאלות נפוצות
איך משפט switch עובד ב-JavaScript?
switch משווה ערך יחיד לסדרה של תוויות case באמצעות שוויון קפדני (===). כשהוא מוצא התאמה, הוא מריץ את הקוד של אותו case וממשיך לרוץ עד שהוא פוגש break או את סוף הבלוק. פסקת default אופציונלית רצה אם אף case לא התאים.
מה זה fallthrough ב-switch של JavaScript?
אם case לא מסתיים ב-break (או ב-return), הביצוע ממשיך ונופל לתוך הקוד של ה-case הבא, גם אם התווית שלו לא התאימה. לפעמים זה שימושי כדי לקבץ cases שחולקים לוגיקה, אבל לרוב זה באג. סיימו תמיד cases ב-break, אלא אם אתם רוצים fallthrough בכוונה.
מתי כדאי להשתמש ב-switch במקום if/else ב-JavaScript?
השתמשו ב-switch כשאתם משווים ערך אחד להרבה אפשרויות קבועות: קודי סטטוס של HTTP, סוגי פעולות, פקודות כמחרוזות. השתמשו ב-if/else כשצריך טווחים, כמה משתנים או ביטויים בוליאניים. זכרו ש-switch משתמש בשוויון קפדני, ולכן case '1' לא יתאים למספר 1.