تکرار کد با حلقه‌ها: for، while، do-while، for...of و for...in

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

  • آشنایی با ساختار حلقه‌ی for و اجزای آن
  • یادگیری تفاوت while و do-while
  • آشنایی با for...of برای پیمایش مقادیر قابل تکرار
  • آشنایی با for...in برای پیمایش کلیدهای یک شیء
  • درک نقش break و continue در کنترل جریان حلقه

مقدمه

یکی از رایج‌ترین نیازها در برنامه‌نویسی، تکرار یک بخش از کد است؛ مثلاً چاپ اعداد از ۱ تا ۱۰، یا پیمایش تمام عناصر یک آرایه. جاوااسکریپت برای این منظور چند نوع حلقه (Loop) در اختیار می‌گذارد که هرکدام کاربرد خاص خود را دارند.

حلقه‌ی for

حلقه‌ی for پرکاربردترین حلقه در جاوااسکریپت است و از سه بخش تشکیل شده: مقداردهی اولیه، شرط ادامه و به‌روزرسانی:

for (let i = 1; i <= 5; i++) {
  console.log(i);
}
// خروجی: 1 2 3 4 5

این سه بخش به ترتیب زیر عمل می‌کنند:

  • let i = 1 — فقط یک‌بار در ابتدا اجرا می‌شود
  • i <= 5 — پیش از هر تکرار بررسی می‌شود؛ اگر Falsy باشد، حلقه متوقف می‌شود
  • i++ — پس از هر تکرار اجرا می‌شود

حلقه‌ی while

حلقه‌ی while فقط یک شرط دارد و تا زمانی که آن شرط Truthy باشد، تکرار می‌شود:

let i = 1;

while (i <= 5) {
  console.log(i);
  i++;
}
// خروجی: 1 2 3 4 5

نکته‌ی مهم: در while، اگر فراموش کنیم متغیر شرط را داخل بدنه‌ی حلقه به‌روزرسانی کنیم، حلقه هرگز متوقف نمی‌شود و به یک حلقه‌ی بی‌نهایت (Infinite Loop) تبدیل می‌شود.

حلقه‌ی do-while

تفاوت do-while با while این است که بدنه‌ی حلقه، پیش از بررسی شرط، حداقل یک‌بار اجرا می‌شود:

let count = 10;

do {
  console.log(count);
  count++;
} while (count < 5);
// خروجی: 10 — فقط یک‌بار اجرا می‌شود، چون شرط از ابتدا Falsy است

تحلیل کد

در مثال بالا، با اینکه شرط count < 5 از همان ابتدا Falsy است، بدنه‌ی حلقه یک‌بار اجرا شده و عدد 10 چاپ می‌شود. این دقیقاً تفاوت اصلی do-while با while است: در while شرط پیش از هر اجرا بررسی می‌شود، اما در do-while شرط پس از اولین اجرا بررسی می‌شود.

for...of — پیمایش مقادیر

for...of برای پیمایش مقادیر داخل ساختارهای Iterable مثل آرایه یا رشته استفاده می‌شود:

let colors = ["قرمز", "سبز", "آبی"];

for (let color of colors) {
  console.log(color);
}
// خروجی: قرمز سبز آبی

در هر مرحله از تکرار، متغیر color مستقیماً برابر با یکی از مقادیر آرایه می‌شود؛ نه اندیس آن. جزئیات دقیق‌تر اینکه چرا آرایه Iterable است، در فصل مربوط به Iterators بررسی می‌شود.

for...in — پیمایش کلیدها

for...in برای پیمایش کلیدهای قابل شمارش (Enumerable) یک شیء استفاده می‌شود:

let user = { name: "علی", age: 25, city: "تهران" };

for (let key in user) {
  console.log(key, user[key]);
}
// خروجی:
// name علی
// age 25
// city تهران

تفاوت مهم for...of و for...in

ویژگیfor...offor...in
کاربرد اصلیپیمایش مقادیر (Array، String و ...)پیمایش کلیدهای یک شیء
روی چه ساختاری کار می‌کندIterableهر شیء با Property های Enumerable
مقدار متغیر حلقهخودِ مقدارنام کلید (Property)
کار روی Object معمولیخطا می‌دهد (مگر Iterable باشد)به‌درستی کار می‌کند

اشتباه رایج این است که for...in برای پیمایش آرایه استفاده شود؛ این کار معمولاً کار می‌کند اما توصیه نمی‌شود، چون for...in تمام Property های قابل شمارش را برمی‌گرداند، از جمله مواردی که ممکن است بعداً به آرایه اضافه شوند و اندیس عددی نباشند.

break و continue

دو کلیدواژه‌ی break و continue برای کنترل جریان حلقه استفاده می‌شوند:

for (let i = 1; i <= 10; i++) {
  if (i === 5) {
    break; // حلقه کاملاً متوقف می‌شود
  }
  console.log(i);
}
// خروجی: 1 2 3 4
for (let i = 1; i <= 5; i++) {
  if (i === 3) {
    continue; // فقط همین تکرار رد می‌شود، حلقه ادامه پیدا می‌کند
  }
  console.log(i);
}
// خروجی: 1 2 4 5

break کل حلقه را متوقف می‌کند، درحالی‌که continue فقط تکرار فعلی را نادیده می‌گیرد و به تکرار بعدی می‌رود.

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

  • فراموش کردن به‌روزرسانی متغیر شرط در while، که منجر به حلقه‌ی بی‌نهایت می‌شود.
  • استفاده از for...in برای پیمایش آرایه به‌جای for...of.
  • خلط کردن break و continue با یکدیگر.

Best Practices

  • برای پیمایش مقادیر آرایه یا رشته، همیشه از for...of استفاده کنید.
  • برای پیمایش کلیدهای یک شیء معمولی، از for...in استفاده کنید.
  • در حلقه‌های while، همیشه مطمئن شوید که شرط در نهایت Falsy می‌شود.

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

حلقه‌ی for...of مستقیماً به مفهوم Iterable و Iterator مرتبط است که در فصل جداگانه‌ای با جزئیات کامل بررسی می‌شود. همچنین، در فصل مربوط به آرایه‌ها، متدهای تکرارکننده‌ای مثل map و forEach را خواهیم دید که در بسیاری از موارد جایگزین مناسب‌تری برای حلقه‌های سنتی هستند.

جمع‌بندی

جاوااسکریپت چند نوع حلقه دارد: for برای تکرار با شمارنده‌ی مشخص، while برای تکرار تا زمانی که شرطی برقرار باشد، و do-while که حداقل یک‌بار اجرا تضمین می‌شود. for...of برای پیمایش مقادیر و for...in برای پیمایش کلیدهای شیء استفاده می‌شود. break و continue نیز ابزارهایی برای کنترل دقیق‌تر جریان حلقه هستند.