404 Not Found

404 Not Found


nginx

الحلقات في جافاسكريبت

الحلقات تتيح لبرنامجك تكرار كتلة من الكود. كتابة "مرحبا" 100 مرة يدويًا غبية — مع حلقة، تكتبها مرة واحدة. هذه هي قوة الحلقات.

حلقة for

حلقة for هي الخيار الأكثر شيوعًا عندما تعرف عدد مرات التكرار:

HTML
<!DOCTYPE html>
<html lang="ar">
<head><meta charset="UTF-8"><title>حلقة for</title></head>
<body>
<div id="output"></div>
<script>
for (let i = 0; i < 5; i++) {
  document.getElementById('output').textContent += i + ' ';
}
</script>
</body>
</html>

الأجزاء الثلاثة:

  1. let i = 0 — التهيئة، تُنفذ مرة واحدة
  2. i < 5 — الشرط، يُتحقق قبل كل تكرار; يستمر فقط إذا كان صحيحًا
  3. i++ — التحديث، يُنفذ بعد كل تكرار
💡 متغيرات الحلقة تُسمى تقليديًا i. للحلقات المتداخلة، استخدم i للخارجية، j للداخلية، وk للمستوى التالي — اتفاقية عالمية للمبرمجين.

مثال: إنشاء قائمة بالحلقات

HTML
<!DOCTYPE html>
<html>
<body>
  <h2>إنشاء قائمة بالحلقات</h2>
  <ul id="list"></ul>
  <script>
    let fruits = ['تفاحة', 'موزة', 'برتقالة', 'عنب', 'بطيخ'];
    let html = '';
    for (let i = 0; i < fruits.length; i++) {
      html += `<li>#${i + 1}: ${fruits[i]}</li>`;
    }
    document.getElementById('list').innerHTML = html;
  </script>
</body>
</html>
▶ جرّب الكود

حلقة while

while تتحقق من الشرط أولاً، ثم تُنفذ — مثالية عندما لا تعرف كم تكرارًا ستحتاج:

HTML
<script>
let count = 0;
while (count < 3) {
  count++;
}
</script>

حالات استخدام شائعة: قراءة البيانات حتى تنتهي، الانتظار حتى يصبح الشرط صحيحًا.

حلقة do...while

do...while تُنفذ مرة واحدة قبل التحقق من الشرط — إنها تعمل مرة واحدة على الأقل:

HTML
<script>
let input;
do {
  input = prompt('أدخل رقمًا موجبًا:');
} while (Number(input) <= 0);
</script>

الفرق عن while في جملة واحدة: while قد لا تعمل أبدًا، لكن do...while تعمل دائمًا مرة واحدة على الأقل.

مثال: مقارنة جميع أنواع الحلقات الثلاثة

HTML
<!DOCTYPE html>
<html>
<body>
  <h2>مقارنة أنواع الحلقات الثلاثة</h2>
  <div id="output"></div>
  <script>
    let html = '<strong>مخرجات حلقة for من 1 إلى 5:</strong><br>';
    for (let i = 1; i <= 5; i++) {
      html += i + ' ';
    }

    html += '<br><br><strong>عد تنازلي بحلقة while:</strong><br>';
    let count = 5;
    while (count > 0) {
      html += count + '... ';
      count--;
    }
    html += 'انطلاق!';

    html += '<br><br><strong>do...while تعمل مرة واحدة على الأقل:</strong><br>';
    let x = 100;
    do {
      html += 'تم التنفيذ! x = ' + x + '<br>';
      x++;
    } while (x < 100);
    // الشرط خاطئ من البداية، لكن كتلة do تعمل مرة واحدة على أي حال

    document.getElementById('output').innerHTML = html;
  </script>
</body>
</html>
▶ جرّب الكود

حلقة for...of

for...of مصممة للتكرار عبر الكائنات القابلة للتكرار (المصفوفات، النصوص، إلخ) بأبسط بنية:

HTML
<!DOCTYPE html>
<html lang="ar">
<head><meta charset="UTF-8"><title>for...of</title></head>
<body>
<div id="output"></div>
<script>
let colors = ['أحمر', 'أخضر', 'أزرق'];
let html = '';
for (let color of colors) {
  html += color + ' ';
}
document.getElementById('output').textContent = html;
</script>
</body>
</html>

على عكس for، for...of تعطيك القيمة، وليس الفهرس. إذا كنت تحتاج الفهرس، استخدم حلقة for تقليدية.

💡 عند تكرار النصوص بـ for...of، تحصل على حرف واحد في كل مرة — حتى أحرف الإيموجي تبقى سليمة، وهو أكثر موثوقية من الوصول القائم على الفهرس.

break وcontinue

HTML
<!DOCTYPE html>
<html lang="ar">
<head><meta charset="UTF-8"><title>break وcontinue</title></head>
<body>
<div id="output"></div>
<script>
// break: توقف عند العثور على الهدف
let breakResult = '';
for (let i = 0; i < 10; i++) {
  if (i === 5) break;
  breakResult += i + ' ';
}

// continue: تخطى الأعداد الزوجية
let continueResult = '';
for (let i = 0; i < 6; i++) {
  if (i % 2 === 0) continue;
  continueResult += i + ' ';
}

document.getElementById('output').innerHTML =
  '<strong>نتيجة break:</strong>' + breakResult + '<br>' +
  '<strong>نتيجة continue:</strong>' + continueResult;
</script>
</body>
</html>

مثال: break وcontinue في العمل

HTML
<!DOCTYPE html>
<html>
<body>
  <h2>break وcontinue</h2>
  <div id="output"></div>
  <script>
    let html = '<strong>break — توقف عند أول عدد زوجي:</strong><br>';
    let nums = [1, 3, 7, 4, 9, 2];
    for (let n of nums) {
      if (n % 2 === 0) {
        html += `وجدنا عددًا زوجيًا ${n}، توقف!`;
        break;
      }
      html += `${n} فردي، متابعة...<br>`;
    }

    html += '<br><br><strong>continue — إخراج الأعداد الفردية فقط:</strong><br>';
    for (let i = 1; i <= 10; i++) {
      if (i % 2 === 0) continue;
      html += i + ' ';
    }

    html += '<br><br><strong>مثال عملي — بحث:</strong><br>';
    let students = [
      { name: 'سارة', score: 95 },
      { name: 'أحمد', score: 72 },
      { name: 'محمد', score: 88 }
    ];
    let found = false;
    for (let s of students) {
      if (s.score >= 90) {
        html += `وجدنا طالبًا متفوقًا: ${s.name} (${s.score} نقطة)`;
        found = true;
        break;
      }
    }
    if (!found) {
      html += 'لا يوجد طالب حصل على 90 أو أكثر';
    }

    document.getElementById('output').innerHTML = html;
  </script>
</body>
</html>
▶ جرّب الكود

حلقات متداخلة

يمكن تعشيق الحلقات داخل حلقات أخرى — تُستخدم بشكل شائع للتعامل مع البيانات ثنائية الأبعاد (جداول، شبكات):

HTML
<!DOCTYPE html>
<html lang="ar">
<head><meta charset="UTF-8"><title>حلقات متداخلة</title></head>
<body>
<div id="output"></div>
<script>
let html = '';
for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    html += `(${i}, ${j}) `;
  }
  html += '<br>';
}
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>

الحلقات المتداخلة تتكاثر في التكلفة — 10 خارجية × 10 داخلية = 100 تكرار. مستويات كثيرة يمكن أن تبطئ الأمور بشكل حاد; إذا كان هناك بديل، تجنب التعشيق العميق.

مثال: جدول الضرب

HTML
<!DOCTYPE html>
<html>
<body>
  <h2>جدول الضرب</h2>
  <table id="table" border="1" cellpadding="6" style="border-collapse:collapse"></table>
  <script>
    let html = '';
    for (let i = 1; i <= 9; i++) {
      html += '<tr>';
      for (let j = 1; j <= i; j++) {
        html += `<td style="text-align:center">${j}×${i}=${i * j}</td>`;
      }
      html += '</tr>';
    }
    document.getElementById('table').innerHTML = html;
  </script>
</body>
</html>
▶ جرّب الكود

فخ الحلقة اللانهائية

إذا كان شرط الحلقة دائمًا صحيحًا، سيتجمد برنامجك — هذه حلقة لانهائية:

HTML
<script>
// ⚠️ لا تفعل هذا أبدًا!
// while (true) {
//   console.log('لا أستطيع التوقف أبدًا!');
// }

// خطأ شائع: نسيان تحديث الشرط
let i = 0;
// while (i < 5) {
//   console.log(i);
//   نسيان i++،所以他 i دائمًا 0 والحلقة لا تنتهي أبدًا
// }
</script>
⚠️ عند كتابة حلقات، تحقق دائمًا من أن الشرط سيصبح في النهاية خاطئًا. وإلا سيتجمد المتصفح وستضطر لإغلاق التلقائي بالقوة.


📖 ملخص

  1. for هي الأكثر شيوعًا لعدد تكرارات معروف; while للشروط المدفوعة; do...while تعمل مرة واحدة على الأقل
  2. for...of هي أبسط طريقة لتكرار المصفوفات — تعطي القيم، وليس الفهارس
  3. break تخرج من الحلقة بأكملها; continue تتخطى إلى التكرار التالي
  4. الحلقات المتداخلة تتكاثر في عدد التكرارات — تجنب الذهاب عميقًا جدًا
  5. تأكد دائمًا من أن شروط الحلقة ستصبح في النهاية خاطئة لتجنب الحلقات اللانهائية

❓ أسئلة شائعة

س ما الفرق بين for...of وfor...in؟
ج for...of تكرر القيم وتعمل مع المصفوفات والكائنات القابلة للتكرار; for...in تكرر المفاتيح (الفهارس) ومخصصة للكائنات. استخدم for...of للمصفوفات — for...in يمكن أن تلتقط خصائص سلسلة النمط وتحسب مشاكل غير متوقعة.
س أي حلقة لها أفضل أداء؟
ج الحلقات التقليدية for هي الأسرع; for...of أبطأ قليلاً لكنها أكثر قراءة. في معظم الحالات فرق الأداء ضئيل — أعطِ الأولوية للقراءة.
س هل break في حلقة متداخلة تخرج من جميع الحلقات أم فقط من الداخلية؟
ج فقط من الحلقة الداخلية. للخروج من حلقة خارجية، استخدم اسم: outer: for(...) { for(...) { break outer; } }. لكن الأسماء تضر القراءة — فكّر في إعادة هيكلة الدالة واستخدام return بدلاً من ذلك.

📝 تمارين

  1. استخدم حلقة for لطباعة جميع مضاعفات 3 بين 1 و100
  2. استخدم حلقات متداخلة لنمط لوحة شطرنج 8×8 (مربعات سوداء وبيضاء متناوبة) على الصفحة
  3. اكتب برنامجًا يأخذ عددًا صحيحًا موجبًا كمدخل ويُخرج المضروب (مثال: الإدخال 5 → 5×4×3×2×1 = 120)
100%