شرح switch في JavaScript: متى تستخدم switch case بدل if else؟
مقدمة إلى جملة switch في JavaScript
في بعض الحالات داخل لغة JavaScript، قد يكون استخدام جملة switch أكثر وضوحًا وتنظيمًا من الاعتماد على سلسلة طويلة من الشروط باستخدام if...else. ويظهر ذلك غالبًا عندما تريد مقارنة قيمة واحدة بعدة احتمالات ثابتة.
بدلًا من كتابة شروط متعددة يصعب تتبعها بصريًا، يمكن أن تمنحك جملة switch أسلوبًا أنظف وأسهل قراءة، خصوصًا في المشاريع التي تهتم بجودة الكود وسهولة صيانته.
لنبدأ بمقارنة مباشرة بين الأسلوبين:
const pet = "dog";
if (pet === "lizard") {
console.log("I own a lizard");
} else if (pet === "dog") {
console.log("I own a dog");
} else if (pet === "cat") {
console.log("I own a cat");
} else if (pet === "snake") {
console.log("I own a snake");
} else if (pet === "parrot") {
console.log("I own a parrot");
} else {
console.log("I don't own a pet");
}
const pet = "dog";
switch (pet) {
case "lizard":
console.log("I own a lizard");
break;
case "dog":
console.log("I own a dog");
break;
case "cat":
console.log("I own a cat");
break;
case "snake":
console.log("I own a snake");
break;
case "parrot":
console.log("I own a parrot");
break;
default:
console.log("I don't own a pet");
break;
}
في هذا المقال ستتعرّف إلى معنى جملة switch، وكيف تعمل داخليًا، ومتى تكون خيارًا مناسبًا داخل كودك البرمجي.

ما هي جملة switch في JavaScript؟
جملة switch هي إحدى أدوات التحكم في تدفّق التنفيذ داخل البرامج. وظيفتها الأساسية هي اختبار قيمة expression ومقارنتها بعدة حالات محتملة تسمى case. وعند العثور على حالة مطابقة، يتم تنفيذ الكود المرتبط بها.
الصيغة الأساسية تكون كالتالي:
switch (expression) {
case 1:
// this code will execute if the case matches the expression
break;
case 2:
// this code will execute if the case matches the expression
break;
case 3:
// this code will execute if the case matches the expression
break;
default:
// this code will execute if none of the cases match the expression
break;
}
كيف تتم المقارنة داخل switch؟
تُجري JavaScript المقارنة داخل switch باستخدام المساواة الصارمة ===. هذا يعني أن التطابق لا يعتمد على القيمة فقط، بل على النوع أيضًا.
بمعنى آخر، إذا كانت القيمة رقمًا 2 فلن تتطابق مع النص "2".
switch (expression) {
case 1:
// this code will execute if the case matches the expression
break;
case 2:
// this code will execute if the case matches the expression
break;
}
إذا لم تتحقق أي حالة من الحالات، فسيتم تنفيذ القسم default:
default:
// this code will execute if none of the cases match the expression
break;
ماذا يحدث عند وجود أكثر من تطابق؟
عند كتابة جملة switch بشكل منطقي، يُفترض أن تكون الحالات مميزة. لكن إن وُجد أكثر من مسار قد يؤدي إلى التطابق، فسيتم تنفيذ أول case مطابق فقط من حيث ترتيب الكتابة.
كما أن وجود break مهم جدًا، لأنه يوقف التنفيذ ويُخرج البرنامج من جملة switch بعد الوصول إلى الحالة الصحيحة. وإذا استخدمت return داخل دالة، فغالبًا لن تحتاج إلى break لأن التنفيذ سيتوقف أصلًا.
مثال عملي على switch case في JavaScript
في المثال التالي تتم مقارنة القيمة "oboe" بعدة حالات. وبما أنها تطابق الحالة الثالثة، فستظهر الرسالة المناسبة في وحدة التحكم:
switch ("oboe") {
case "trumpet":
console.log("I play the trumpet");
break;
case "flute":
console.log("I play the flute");
break;
case "oboe":
console.log("I play the oboe");
break;
default:
console.log("I don't play an instrument. Sorry");
break;
}
أما إذا غيّرت قيمة expression إلى "no instrument" فلن يحدث أي تطابق، وعندها سيتم تنفيذ default:
switch ("no instrument") {
case "trumpet":
console.log("I play the trumpet");
break;
case "flute":
console.log("I play the flute");
break;
case "oboe":
console.log("I play the oboe");
break;
default:
console.log("I don't play an instrument. Sorry");
break;
}
أهمية break داخل جملة switch
من أكثر الأخطاء شيوعًا عند استخدام switch نسيان كتابة break. عند غيابها، لا يتوقف التنفيذ عند الحالة المطابقة، بل ينتقل إلى الحالات التالية ويستمر في التنفيذ حتى يصل إلى break أو نهاية الجملة.
هذا السلوك يُعرف باسم fall-through، وقد يكون مفيدًا أحيانًا، لكنه في كثير من الحالات يسبب نتائج غير مقصودة.
switch (2) {
case 1:
console.log("Number 1 was chosen");
case 2:
console.log("Number 2 was chosen");
case 3:
console.log("Number 3 was chosen");
default:
console.log("No number was chosen");
}
في هذا المثال، ورغم أن التطابق يحدث عند case 2، فإن غياب break يؤدي إلى تنفيذ ما بعده أيضًا، لذلك ستظهر عدة رسائل بدل رسالة واحدة.

أين تضع default داخل switch؟
المتعارف عليه برمجيًا هو وضع default في آخر جملة switch، لأنه يمثل المسار الاحتياطي عند عدم تحقق أي حالة. لكن من الناحية التقنية، يمكن وضعه في مكان آخر أيضًا.
const food = "nuts";
switch (food) {
case "cake":
console.log("I like cake");
break;
case "pizza":
console.log("I like pizza");
break;
default:
console.log("I like all foods");
break;
case "ice cream":
console.log("I like ice cream");
break;
}
سيستمر المحرّك في فحص الحالات، وبما أن المتغير food لا يطابق أيًا منها، فسيتم تنفيذ default.

تنفيذ عملية واحدة لعدة حالات
أحيانًا تحتاج إلى تنفيذ نفس العملية عند تطابق أكثر من قيمة. بدل تكرار نفس السطر لكل case، يمكنك جمع الحالات معًا وكتابة العملية مرة واحدة فقط.
في المثال التالي، ستظهر الرسالة نفسها إذا كانت قيمة country واحدة من عدة دول أوروبية:
const country = "Ireland";
switch (country) {
case "France":
case "Spain":
case "Ireland":
case "Poland":
console.log("This country is in Europe.");
break;
case "United States":
default:
console.log("This country is not in Europe.");
}
هذا الأسلوب مفيد عندما تتشارك عدة حالات النتيجة نفسها، كما أنه يقلل التكرار ويحافظ على نظافة الكود.
نطاق المتغيرات داخل switch
من النقاط المهمة التي يغفل عنها بعض المطورين أن جميع حالات switch تشترك في نفس النطاق العام للجملة، ما لم تُنشئ نطاقًا مستقلًا باستخدام الأقواس المعقوفة {}.
لذلك إذا أعلنت متغيرًا باستخدام let بالاسم نفسه داخل أكثر من case، فقد يظهر خطأ لأن الاسم أُعلن مسبقًا ضمن نفس النطاق.
const errand = "Going Shopping";
switch (errand) {
case "Going to the Dentist":
let message = "I hate going to the dentist";
console.log(message);
break;
case "Going Shopping":
let message = "I love to shop";
console.log(message);
break;
default:
console.log("No errands");
break;
}
هذا المثال سينتج خطأ بسبب تكرار تعريف المتغير message.

الحل الصحيح لمشكلة block scope
لتفادي هذه المشكلة، يمكنك وضع كل case داخل كتلة مستقلة باستخدام الأقواس المعقوفة، بحيث يصبح لكل حالة نطاقها الخاص.
const errand = "Going Shopping";
switch (errand) {
case "Going to the Dentist": {
let message = "I hate going to the dentist";
console.log(message);
break;
}
case "Going Shopping": {
let message = "I love to shop";
console.log(message);
break;
}
default: {
console.log("No errand");
break;
}
}
بهذا الأسلوب يصبح كل متغير محصورًا داخل كتلته، ويزول التعارض بين الأسماء المتشابهة.

متى تكون switch أفضل من if...else؟
ليست جملة switch بديلًا مطلقًا عن if...else، لكن هناك حالات تكون فيها أكثر ملاءمة، مثل:
- عند مقارنة متغير واحد بعدة قيم ثابتة.
- عند الرغبة في جعل الكود أسهل قراءة بصريًا.
- عند وجود حالات متعددة تؤدي إلى النتيجة نفسها.
- عند الحاجة إلى بنية منظمة تسهّل الصيانة مستقبلًا.
أما إذا كانت الشروط تعتمد على تعبيرات منطقية معقدة، أو مقارنات مركبة باستخدام > و< وعمليات منطقية متعددة، فغالبًا يكون استخدام if...else أوضح وأكثر مرونة.
ملاحظات مهمة عند استخدام switch في JavaScript
- تأكّد من فهمك لسلوك المساواة الصارمة
===. - لا تنسَ
breakإلا إذا كنت تريد عمدًا استخدامfall-through. - استخدم
defaultكمسار احتياطي للتعامل مع القيم غير المتوقعة. - عند استخدام
letأوconstداخل الحالات، فكّر في إنشاء كتل مستقلة. - احرص على أن تكون جملة
switchوسيلة لتحسين الوضوح، لا مجرد استبدال شكلي لـif...else.
مثال يوضح المساواة الصارمة داخل switch
في المثال التالي، لن تتطابق القيمة الرقمية 2 مع النص "2"، لذلك سيتم تنفيذ default:
switch (2) {
case "2":
console.log("Number 2 in a string");
break;
case "3":
console.log("Number 3 in a string");
break;
default:
console.log("Number not present");
break;
}
هذا المثال يبرز بوضوح أن switch لا يجري تحويلًا ضمنيًا للنوع عند المقارنة، بل يعتمد على التطابق الصارم بين القيمة والنوع.
الخلاصة التقنية
تُعد جملة switch في JavaScript خيارًا ممتازًا عندما تحتاج إلى مقارنة قيمة واحدة بعدة حالات محددة وواضحة. قوتها الحقيقية تظهر في تحسين قابلية القراءة وتقليل التشعّب الناتج عن if...else الطويلة. ومع ذلك، يجب استخدامها بوعي، خصوصًا فيما يتعلق بسلوك break، والمقارنة الصارمة ===، ونطاق المتغيرات داخل الحالات. إذا كان هدفك كتابة كود أنظف وأسهل صيانة، ففهم switch case بشكل صحيح سيمنحك أداة فعّالة ضمن أساسيات البرمجة الحديثة.