Higher Order Functions – forEach 

ما هي forEach في JavaScript؟

forEach هي دالة عليا (Higher-Order Function) تُستخدم لتنفيذ وظيفة أو كود معين على كل عنصر في المصفوفة.

📌 لكنها لا ترجع قيمة (أي لا تُرجع مصفوفة أو ناتج مثل map أو filter).

📦 الصيغة:

array.forEach(function(element, index, array) {
  // كود يتم تنفيذه على كل عنصر
});
///////////////////////// السهم
array.forEach((element, index, array) => {
  // كود التنفيذ
});
JavaScript
📌 المعاملات:
المعاملالوظيفة
elementالعنصر الحالي
indexرقم الفهرس (اختياري)
arrayالمصفوفة الأصلية (اختياري)
🔁 الفرق بينها وبين map
خاصيةforEachmap
تُرجع قيمة؟❌ لا✅ نعم (مصفوفة جديدة)
التعديل على العناصر؟✅ ممكن (لكن لا ترجع)✅ ترجع التعديلات
الاستخدام المفضلتنفيذ أوامرتعديل القيم وإنشاء مصفوفة جديدة

🧪 أمثلة عملية ومشروحة

✅ طباعة كل عنصر في المصفوفة

const names = ["Ali", "Sara", "Omar"];

names.forEach((name) => {
  console.log(name);
});
// الناتج:
// Ali
// Sara
// Omar
JavaScript

✅ طباعة كل عنصر مع رقمه (الفهرس)

const items = ["Book", "Pen", "Notebook"];

items.forEach((item, index) => {
  console.log(`Item ${index + 1}: ${item}`);
});
// Item 1: Book
// Item 2: Pen
// Item 3: Notebook
JavaScript

✅ جمع كل الأرقام (باستخدام متغير خارجي)

const numbers = [1, 2, 3, 4, 5];
let sum = 0;

numbers.forEach(num => {
  sum += num;
});

console.log(sum); // 15
JavaScript

❗لاحظ أن forEach لا ترجع القيمة، لذلك استخدمنا متغير خارجي لتجميع القيم.

✅ إنشاء مصفوفة جديدة يدويًا (بدون map)

const nums = [1, 2, 3];
const doubled = [];

nums.forEach(num => {
  doubled.push(num * 2);
});

console.log(doubled); // [2, 4, 6]
JavaScript

نريد تغيير لون جميع العناصر التي تحمل الكلاس .box إلى الأحمر.

<div class="box">Box 1</div>
<div class="box">Box 2</div>
<div class="box">Box 3</div>

///////////////////////////////////////

const boxes = document.querySelectorAll('.box');

boxes.forEach(function(box) {
  box.style.color = 'red';
});
JavaScript

لاحظ أننا نستطيع القيام بذلك بـ map مباشرة، لكن forEach أداة يدوية أكثر.

⚠️ ملاحظات مهمة جدًا:
  1. forEach لا تُستخدم للتعديلات التي تحتاج إلى قيمة ناتجة.
    • إذا كنت تحتاج نتيجة → استخدم map أو reduce.
  2. لا يمكن كسر التكرار باستخدام break أو return مثل الحلقات التقليدية.
    • إذا كنت تريد الخروج مبكرًا → استخدم for أو some.
  3. يمكن استخدامها لأغراض جانبية مثل:
    • الطباعة.
    • حفظ القيم في مصفوفة خارجية.
    • تعديل الكائنات داخل المصفوفة.
📌 متى أستخدم forEach بدل map؟
الحالةاستخدم
تريد تنفيذ كود فقط بدون نتيجةforEach
تريد تعديل القيم وإنشاء مصفوفة جديدةmap
تريد تصفية القيمfilter
تريد تحويل كل العناصر إلى شيء واحد (مجموع، كائن…)reduce
💡 تمرين سريع:

استخدم forEach لطباعة فقط الأرقام الفردية من مصفوفة:

const numbers = [1, 2, 3, 4, 5, 6];

numbers.forEach(num => {
  if (num % 2 !== 0) {
    console.log(num);
  }
});
// 1
// 3
// 5
JavaScript
📊 جدول مقارنة شامل:
الخاصيةforEachmapfilterreduce
✅ ترجع قيمة؟❌ لا ترجع (undefined)✅ ترجع مصفوفة جديدة✅ ترجع مصفوفة جديدة مصفّاة✅ ترجع قيمة واحدة فقط
✅ هل تغير المصفوفة؟❌ لا مباشرة، لكن يمكن التعديل على الكائنات❌ لا، ترجع نسخة معدّلة❌ لا، ترجع نسخة تحتوي القيم المطابقة❌ لا، لكن يمكنك بناء ما تريد داخلها
✅ القيمة الابتدائية؟❌ غير مستخدمة❌ غير مطلوبة❌ غير مطلوبة✅ مطلوبة (اختياري لكن مفضل بشدة)
🧠 تستخدم للـ Side Effects؟✅ نعم (مثل الطباعة – push – تعديل خارجي)❌ نادرًا (تستخدم للنتائج)
🎯 الهدف منها؟تنفيذ كود على كل عنصرتعديل وتحويل العناصرتصفية العناصرتجميع وتحويل القيم إلى قيمة واحدة
🧠 هل يمكن الاستغناء عنها؟✅ يمكن استبدالها بـ for أو map أحيانًا❌ الأفضل لها استخدام خاص❌ تستخدم فقط للتصفية❌ فريدة وقوية لحالات التحويل المتقدمة
🚫 كسر التكرار (break❌ لا يمكن❌ لا يمكن❌ لا يمكن❌ لا يمكن
📝 أمثلة عملية مبسطة:
الدالةمثال
forEachطباعة كل الأسماء في المصفوفة
mapضرب كل رقم في 2 وإنشاء مصفوفة جديدة
filterإرجاع فقط الأرقام الأكبر من 10
reduceحساب مجموع كل الأرقام
🧠 نصيحة ختامية:
  • forEach: عندما تريد تنفيذ كود جانبي (log, push, تعديل).
  • 🔄 map: عندما تحتاج إنشاء مصفوفة معدّلة.
  • 🧹 filter: عندما تحتاج تصفية البيانات.
  • 🧮 reduce: عندما تريد حساب/تحويل/تجميع المصفوفة لقيمة واحدة (رقم، كائن، نص…).