← الدرس السابق المستوى 3 - الدرس 4 من 10

🔄 الحلقات (Loops) في JavaScript: الدليل الشامل للتكرار

تعلم كيف تكرر العمليات بكفاءة باستخدام for, while, do...while و for...of مع أمثلة واقعية

تقدمك في المستوى الثالث 40%

📋 محتويات الدرس

  1. لماذا نحتاج الحلقات؟
  2. for loop — التكرار بعدد محدد
  3. while loop — التكرار حتى تحقق شرط
  4. do...while — التنفيذ مرة واحدة على الأقل
  5. for...of — التكرار على المصفوفات
  6. for...in — التكرار على خصائص الكائن
  7. break و continue — التحكم في التكرار
  8. الحلقات المتداخلة
  9. تجنب الحلقات اللانهائية
  10. أمثلة واقعية من التطبيقات
  11. أداء الحلقات ونصائح التحسين
  12. اختبر فهمك — اختبار تفاعلي

🤔 لماذا نحتاج الحلقات؟

تخيل إنك عايز تطبع "مرحباً" 100 مرة. بدون حلقات، هتكتب:

console.log("مرحباً"); console.log("مرحباً"); console.log("مرحباً"); // ... تكرار 97 مرة أخرى!

هذا غير عملي وغير قابل للصيانة. الحلقات (Loops) هي الحل — تسمح لك بتكرار كود معين عدد معين من المرات أو حتى تحقق شرط معين.

💡 متى نستخدم الحلقات في التطبيقات الحقيقية؟
  • عرض قائمة منتجات في متجر إلكتروني
  • البحث في مصفوفة بيانات
  • معالجة كل حرف في نص
  • تكرار طلبات API حتى الحصول على نتيجة
  • حساب إجمالي سعر المنتجات في عربة التسوق

🔄 for loop — التكرار بعدد محدد

أشهر نوع حلقة في JavaScript. تُستخدم عندما تعرف مسبقاً عدد مرات التكرار.

البنية الأساسية

// for (تعريف المتغير; الشرط; التحديث) for (let i = 0; i < 5; i++) { console.log(i); // 0, 1, 2, 3, 4 }

كيف تعمل for loop؟

  1. Initialization: let i = 0 — يُنفذ مرة واحدة في البداية
  2. Condition: i < 5 — يُفحص قبل كل تكرار. إذا false، تتوقف الحلقة
  3. Body: الكود داخل الأقواس — يُنفذ إذا كان الشرط true
  4. Update: i++ — يُنفذ بعد كل تكرار

أمثلة عملية

// طباعة جدول الضرب لـ 5 for (let i = 1; i <= 10; i++) { console.log(`5 × ${i} = ${5 * i}`); } // الناتج: 5 × 1 = 5, 5 × 2 = 10, ... حتى 5 × 10 = 50 // حساب مجموع الأرقام من 1 إلى 100 let sum = 0; for (let i = 1; i <= 100; i++) { sum += i; } console.log(sum); // 5050 // تكرار عكسي for (let i = 10; i >= 1; i--) { console.log(i); // 10, 9, 8, ..., 1 }
✅ نصيحة:

استخدم i كاسم للعداد في الحلقات — هذا اتفاق عالمي بين المطورين. لو عندك حلقات متداخلة، استخدم i, j, k.

🔄 while loop — التكرار حتى تحقق شرط

تُستخدم عندما لا تعرف عدد مرات التكرار مسبقاً. الحلقة تستمر طالما الشرط صحيح.

let count = 0; while (count < 5) { console.log(count); count++; // ⚠️ لا تنسَ الزيادة! }

مثال واقعي: طلب بيانات من المستخدم

// محاكاة: استمر في الطلب حتى يُدخل المستخدم قيمة صالحة let userInput = ""; let attempts = 0; while (userInput === "" && attempts < 3) { // userInput = prompt("أدخل اسمك:"); attempts++; console.log(`محاولة ${attempts}`); }

🔄 do...while — التنفيذ مرة واحدة على الأقل

مثل while لكنها تنفذ الكود مرة واحدة على الأقل قبل فحص الشرط. مفيدة عندما تحتاج لتنفيذ الكود أولاً ثم التحقق.

let num = 0; do { console.log(num); // يُنفذ دائماً مرة واحدة num++; } while (num < 5);

متى تستخدم do...while؟

// قائمة طعام: اعرض القائمة مرة واحدة على الأقل let choice; do { console.log("1. بيتزا 2. برجر 3. خروج"); // choice = getUserInput(); } while (choice !== "3");

🎯 for...of — التكرار على المصفوفات

أسهل طريقة للتكرار على عناصر المصفوفة (أو أي iterable). لا تحتاج لمعرفة الفهرس (index).

let fruits = ["تفاح", "موز", "برتقال", "عنب"]; // ✅ for...of — نظيف وواضح for (let fruit of fruits) { console.log(`أحب ${fruit}`); } // الناتج: أحب تفاح, أحب موز, أحب برتقال, أحب عنب // ❌ for التقليدي — أطول وأقل وضوحاً for (let i = 0; i < fruits.length; i++) { console.log(fruits[i]); }
✅ القاعدة:

استخدم for...of للمصفوفات (القيم). استخدم for العادي إذا احتجت للفهرس (index). استخدم for...in للكائنات (المفاتيح).

🔑 for...in — التكرار على خصائص الكائن

تُستخدم للتكرار على مفاتيح (keys) الكائن. لا تستخدمها للمصفوفات — يمكن أن تتضمن خصائص موروثة.

let user = { name: "أحمد", age: 25, city: "القاهرة" }; for (let key in user) { console.log(`${key}: ${user[key]}`); } // الناتج: name: أحمد, age: 25, city: القاهرة

🛑 break و continue — التحكم في التكرار

break — إيقاف الحلقة فوراً

يُستخدم للخروج من الحلقة عند تحقق شرط معين:

// البحث عن رقم في مصفوفة let numbers = [4, 7, 2, 9, 1]; let target = 9; let found = false; for (let i = 0; i < numbers.length; i++) { if (numbers[i] === target) { console.log(`وجدته في الفهرس ${i}`); found = true; break; // ✅ توقف — لا داعي للبحث أكثر } }

continue — تخطي التكرارة الحالية

يُستخدم لتخطي باقي الكود في التكرارة الحالية والانتقال للتكرارة التالية:

// طباعة الأرقام الفردية فقط for (let i = 0; i < 10; i++) { if (i % 2 === 0) { continue; // تخطي الأرقام الزوجية } console.log(i); // 1, 3, 5, 7, 9 }

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

حلقة داخل حلقة. مفيدة لمعالجة البيانات ثنائية الأبعاد (مثل الجداول):

// طباعة جدول الضرب كامل for (let i = 1; i <= 5; i++) { let row = ""; for (let j = 1; j <= 5; j++) { row += `${i * j}\t`; } console.log(row); } // الناتج: // 1 2 3 4 5 // 2 4 6 8 10 // ...
⚠️ تحذير الأداء:

حلقة متداخلة من 100×100 = 10,000 تكرار. من 1000×1000 = 1,000,000 تكرار! كن حذراً مع الحلقات المتداخلة — قد تُبطئ التطبيق بشكل كبير.

⚠️ تجنب الحلقات اللانهائية

الحلقة اللانهائية (Infinite Loop) تستمر للأبد وتُجمّد المتصفح. أسبابها الشائعة:

// ❌ خطأ 1: نسيان الزيادة let i = 0; while (i < 10) { console.log(i); // i++ نسيت هذا! } // ❌ خطأ 2: الشرط دائماً true while (true) { console.log("لن تتوقف!"); } // ✅ صحيح: شرط للخروج let running = true; let counter = 0; while (running) { console.log(counter); counter++; if (counter >= 10) { running = false; // شرط واضح للخروج } }
🚨 إذا جمّد المتصفح:

اضغط Ctrl+Shift+Esc (Windows) أو Cmd+Option+Esc (Mac) لإغلاق التبويب. في Chrome، يمكنك فتح Task Manager من القائمة → More Tools → Task Manager.

💼 أمثلة واقعية من التطبيقات

1. حساب إجمالي سعر المنتجات

let cart = [ { name: "هاتف", price: 5000 }, { name: "سماعات", price: 500 }, { name: "شاحن", price: 150 } ]; let total = 0; for (let item of cart) { total += item.price; } console.log(`الإجمالي: ${total} جنيه`); // 5650

2. البحث عن مستخدم بالاسم

let users = ["أحمد", "سارة", "محمد", "فاطمة"]; let searchName = "محمد"; let found = false; for (let i = 0; i < users.length; i++) { if (users[i] === searchName) { console.log(`✅ وجدته في الفهرس ${i}`); found = true; break; } } if (!found) { console.log("❌ المستخدم غير موجود"); }

3. فلترة المنتجات حسب السعر

let products = [ { name: "لابتوب", price: 15000 }, { name: "ماوس", price: 200 }, { name: "كيبورد", price: 350 }, { name: "شاشة", price: 3000 } ]; let affordable = []; for (let product of products) { if (product.price <= 1000) { affordable.push(product); } } console.log("منتجات بأقل من 1000:", affordable);

⚡ أداء الحلقات ونصائح التحسين

النصيحة الشرح الفائدة
تخزين length في متغير for (let i=0, len=arr.length; i<len; i++) تجنب قراءة length في كل تكرار
استخدام break عند البحث توقف فوراً عند العثور على النتيجة توفير وقت كبير في المصفوفات الكبيرة
تجنب DOM داخل الحلقة لا تعدل DOM في كل تكرار DOM بطيء — اجمع التغييرات ثم طبقها مرة واحدة
استخدام for...of بدلاً من for أنظف وأسرع للمصفوفات قراءة أفضل + أداء مماثل

🚀 الخطوة التالية: الدوال (Functions)

في الدرس الخامس، ستتعلم كيف تُنشئ كود قابل لإعادة الاستخدام:

  • 🔧 تعريف الدوال: function declaration و expression
  • 📥 المعاملات (Parameters): تمرير بيانات للدالة
  • 📤 return: إرجاع نتيجة
  • 🎯 Arrow Functions: الدوال السهمية الحديثة
📚 مصادر إضافية:
← الدرس السابق: العمليات الحسابية