تصمیم‌گیری در کد با if/else و switch

اهداف یادگیری

  • یادگیری ساختار if، else if و else
  • آشنایی با ساختار switch و نحوه‌ی عملکرد آن
  • درک مفهوم Fall-through در switch و نقش break
  • توانایی انتخاب بین if/else و switch بر اساس موقعیت

مقدمه

در درس قبل با عملگرهای مقایسه‌ای و منطقی آشنا شدیم؛ حالا وقت آن است که ببینیم چطور از این عملگرها برای تصمیم‌گیری در کد استفاده می‌کنیم. جاوااسکریپت دو ابزار اصلی برای این کار در اختیار می‌گذارد: ساختار if/else و ساختار switch.

if ساده

let age = 20;

if (age >= 18) {
  console.log("بزرگ‌سال است");
}

اگر شرط داخل پرانتز Truthy باشد، بلاک کد داخل {} اجرا می‌شود؛ در غیر این صورت، هیچ‌کاری انجام نمی‌شود.

if/else

let age = 15;

if (age >= 18) {
  console.log("بزرگ‌سال است");
} else {
  console.log("کمتر از ۱۸ سال است");
}

if/else if/else

وقتی چند شرط متوالی داریم، از else if استفاده می‌کنیم:

let score = 75;

if (score >= 90) {
  console.log("عالی");
} else if (score >= 70) {
  console.log("خوب");
} else if (score >= 50) {
  console.log("متوسط");
} else {
  console.log("ضعیف");
}
// خروجی: "خوب"

تحلیل کد

نکته‌ی مهم این است که شرط‌ها به ترتیب از بالا به پایین بررسی می‌شوند و به‌محض یافتن اولین شرط Truthy، همان بلاک اجرا و از کل ساختار خارج می‌شویم؛ حتی اگر شرط‌های بعدی هم Truthy باشند. در مثال بالا، score >= 70 اولین شرط Truthy است، پس بلاک آن اجرا می‌شود و به شرط‌های بعدی اصلاً بررسی نمی‌شوند.

switch — جایگزین شرط‌های متوالی

وقتی می‌خواهیم یک مقدار واحد را با چند حالت مشخص مقایسه کنیم، ساختار switch معمولاً خواناتر از زنجیره‌ی طولانی else if است:

let day = "سه‌شنبه";

switch (day) {
  case "شنبه":
    console.log("شروع هفته");
    break;
  case "سه‌شنبه":
    console.log("وسط هفته");
    break;
  case "پنجشنبه":
    console.log("پایان هفته کاری");
    break;
  default:
    console.log("روز عادی");
}
// خروجی: "وسط هفته"

نقش break در switch

جاوااسکریپت مقدار day را با هر case با عملگر === (Strict Equality) مقایسه می‌کند. به‌محض یافتن تطابق، کد داخل همان case اجرا می‌شود. اما نکته‌ی حیاتی اینجاست: اگر break ننویسیم، اجرا به case بعدی هم سرریز می‌کند، حتی اگر شرط آن برقرار نباشد. به این رفتار Fall-through می‌گویند:

let day = "شنبه";

switch (day) {
  case "شنبه":
    console.log("شروع هفته");
  case "سه‌شنبه":
    console.log("وسط هفته");
    break;
  default:
    console.log("روز عادی");
}
// خروجی:
// "شروع هفته"
// "وسط هفته"

در این مثال، چون break بعد از case "شنبه" وجود ندارد، اجرا به case بعدی هم ادامه پیدا می‌کند و هر دو پیام چاپ می‌شوند؛ درحالی‌که در اکثر مواقع این رفتار مطلوب ما نیست.

استفاده‌ی عمدی از Fall-through

گاهی Fall-through عمداً و برای گروه‌بندی چند حالت مشابه استفاده می‌شود:

let month = "دی";

switch (month) {
  case "آذر":
  case "دی":
  case "بهمن":
    console.log("فصل زمستان");
    break;
  default:
    console.log("فصل دیگر");
}
// خروجی: "فصل زمستان"

در این حالت، چون هیچ break‌ای بین case های "آذر"، "دی" و "بهمن" وجود ندارد، هر سه به یک بلاک کد مشترک منتهی می‌شوند.

اشتباهات رایج

  • فراموش کردن break در switch که باعث اجرای ناخواسته‌ی case های بعدی می‌شود.
  • تصور اینکه switch از مقایسه‌ی Loose (مثل ==) استفاده می‌کند؛ درحالی‌که همیشه از Strict Equality (===) استفاده می‌شود.
  • استفاده از switch برای شرط‌های بازه‌ای (مثل بزرگ‌تر یا کوچک‌تر بودن) که برای آن‌ها if/else مناسب‌تر است.

Best Practices

  • برای شرط‌های بازه‌ای (مثل نمره یا سن) از if/else if استفاده کنید.
  • برای مقایسه‌ی یک مقدار با چند حالت مشخص و گسسته (مثل روز هفته یا وضعیت سفارش)، از switch استفاده کنید.
  • همیشه یک default در switch در نظر بگیرید تا حالت‌های پیش‌بینی‌نشده هم مدیریت شوند.
  • هرگز فراموش نکنید که در انتهای هر case (به‌جز مواردی که عمداً Fall-through می‌خواهید) از break استفاده کنید.

ارتباط با سایر مفاهیم

درک درست if/else و switch پیش‌نیاز درس بعدی درباره‌ی حلقه‌هاست؛ چون در بسیاری از حلقه‌ها، از شرط‌های مشابه برای کنترل روند تکرار استفاده می‌شود.

جمع‌بندی

ساختار if/else برای بررسی شرط‌های منطقی و بازه‌ای مناسب است، درحالی‌که switch برای مقایسه‌ی یک مقدار با چند حالت گسسته خوانایی بهتری دارد. نکته‌ی حیاتی در switch این است که بدون break، اجرا به case بعدی هم سرریز می‌کند؛ رفتاری که باید همیشه آگاهانه مدیریت شود.