📖 ما هي الدوال ولماذا نحتاجها؟
الدالة (Function) هي كتلة من الكود المُسمّاة يمكن استدعاؤها عدة مرات. بدلاً من كتابة نفس الكود 10 مرات، تكتبه مرة واحدة في دالة وتستدعيها 10 مرات.
💡 لماذا الدوال مهمة جداً؟
- 🔄 إعادة الاستخدام: اكتب مرة واحدة، استخدم ألف مرة
- 🧹 التنظيم: تقسيم الكود الكبير لقطع صغيرة مفهومة
- 🐛 سهولة التصحيح: إذا فيه خطأ، تصلحه في مكان واحد
- 🤝 التعاون: مطورون مختلفون يعملون على دوال مختلفة
- 📦 التجريد (Abstraction): تخفي التعقيد وتُظهر الواجهة البسيطة
مثال من الحياة: تخيل إنك بتعمل "سندويتش". بدلاً ما تشرح كل خطوة كل مرة (خبز، جبنة، لحمة، خس، خبز)، تقول ببساطة "اعمل سندويتش". الدالة هي "اعمل سندويتش" — تخفي التفاصيل وتُبسّط الاستخدام.
🎯 تعريف الدالة — Function Declaration
أبسط طريقة لتعريف دالة في JavaScript. تبدأ بكلمة function متبوعة بالاسم:
function sayHello() {
console.log("مرحباً بالعالم!");
}
sayHello();
sayHello();
sayHello();
خصائص Function Declaration
- ✅ Hoisting: يمكن استدعاؤها قبل تعريفها في الكود
- ✅ اسم واضح: يسهل تصحيح الأخطاء (Stack Trace)
- ✅ نطاق عام (Global): متاحة في كل مكان في الملف
greet("أحمد");
function greet(name) {
console.log(`أهلاً ${name}`);
}
📥 المعاملات (Parameters) والوسائط (Arguments)
المعاملات (Parameters) هي المتغيرات التي تُعرّفها في الدالة. الوسائط (Arguments) هي القيم الفعلية التي تُمرّرها عند الاستدعاء.
function greet(name, age) {
console.log(`أهلاً ${name}، عمرك ${age} سنة`);
}
greet("أحمد", 25);
greet("سارة", 30);
عدد متغير من الوسائط — arguments object
function sumAll() {
let total = 0;
for (let num of arguments) {
total += num;
}
return total;
}
console.log(sumAll(1, 2, 3));
console.log(sumAll(10, 20));
⚠️ ملاحظة:
في JavaScript الحديثة، استخدم Rest Parameters ...args بدلاً من arguments — أنظف وأكثر مرونة.
↩️ return — إرجاع القيم وإيقاف الدالة
return يُستخدم لإرجاع قيمة من الدالة إلى المكان الذي استُدعيت منه. كما أنه يوقف تنفيذ الدالة فوراً — أي كود بعد return لن يُنفّذ.
function add(a, b) {
return a + b;
}
let result = add(5, 3);
console.log(result);
function checkAge(age) {
if (age < 18) {
return "❌ قاصر";
}
return "✅ بالغ";
}
console.log(checkAge(15));
console.log(checkAge(25));
❌ خطأ شائع:
لا تضع سطر جديد بعد return بدون أقواس — JavaScript تُضيف فاصلة منقوطة تلقائياً!
return
a + b; // ✗ يرجع undefined!
📝 Function Expression و Anonymous Functions
بدلاً من تعريف الدالة باسم، يمكنك تخزينها في متغير. هذه Function Expression:
const multiply = function(a, b) {
return a * b;
};
console.log(multiply(4, 5));
const greet = function(name) {
console.log(`أهلاً ${name}`);
};
الفرق بين Declaration و Expression
| الخاصية |
Function Declaration |
Function Expression |
| Hoisting |
✓ نعم |
✗ لا |
| الاسم |
إلزامي |
اختياري (anonymous) |
| متى تستخدم |
الدوال العامة |
الدوال المُمررة كمعاملات |
⚡ Arrow Functions — الدوال السهمية الحديثة
أضيفت في ES6 (2015). صيغة مختصرة وأكثر وضوحاً للدوال البسيطة. خاصة مفيدة للـ Callbacks.
التطور من القديم للحديث
function multiply(x) {
return x * 2;
}
const multiply = function(x) {
return x * 2;
};
const multiply = (x) => {
return x * 2;
};
const multiply = x => x * 2;
const add = (a, b) => a + b;
const square = x => x * x;
const greet = () => "مرحباً!";
قواعد اختصار Arrow Functions
| الحالة |
الصيغة |
مثال |
| معامل واحد |
بدون أقواس |
x => x * 2 |
| معاملات متعددة أو صفر |
مع أقواس |
(a, b) => a + b |
| سطر واحد + return |
بدون أقواس متعرجة و return |
x => x * x |
❌ لا تستخدم Arrow Functions إذا:
- تحتاج
this — Arrow Functions لا تملك this خاص بها
- تحتاج
arguments object — غير متاح
- تُستخدم كـ Constructor (مع
new) — لا يمكن
🎯 القيم الافتراضية للمعاملات
يمكنك تحديد قيمة افتراضية للمعامل. إذا لم يُمرّر الوسيط، تُستخدم القيمة الافتراضية:
function greet(name = "زائر") {
console.log(`أهلاً ${name}`);
}
greet();
greet("علي");
function createUser(name, role = "user", isActive = true) {
return { name, role, isActive };
}
console.log(createUser("أحمد"));
console.log(createUser("سارة", "admin"));
🔒 نطاق المتغيرات (Scope) داخل الدوال
المتغيرات المُعلنة داخل دالة لا يمكن الوصول إليها من خارجها. هذا يسمى Function Scope:
function calculate() {
let result = 42;
console.log(result);
}
calculate();
Closure — إغلاق النطاق
الدوال الداخلية يمكنها الوصول لمتغيرات الدالة الخارجية:
function outer() {
let count = 0;
function inner() {
count++;
return count;
}
return inner;
}
const counter = outer();
console.log(counter());
console.log(counter());
console.log(counter());
🔄 Callback Functions — الدوال كمعاملات
في JavaScript، الدوال هي قيم من الدرجة الأولى (First-Class Citizens) — يمكن تمريرها كمعاملات، وتخزينها في متغيرات، وإرجاعها من دوال أخرى.
function doSomething(callback) {
console.log("أعمل شيئاً...");
callback();
}
doSomething(() => {
console.log("✅ تم الانتهاء!");
});
let fruits = ["تفاح", "موز", "برتقال"];
fruits.forEach((fruit, index) => {
console.log(`${index + 1}. ${fruit}`);
});
🏆 Higher-Order Functions — دوال من الدرجة الأولى
دوال تأخذ دوالاً كمعاملات أو تُرجع دوالاً. هذه أساس البرمجة الوظيفية في JavaScript:
let numbers = [1, 2, 3, 4, 5];
let doubled = numbers.map(n => n * 2);
console.log(doubled);
let evens = numbers.filter(n => n % 2 === 0);
console.log(evens);
let sum = numbers.reduce((total, n) => total + n, 0);
console.log(sum);
💼 أمثلة واقعية من التطبيقات
1. التحقق من صحة البريد الإلكتروني
function isValidEmail(email) {
if (!email || !email.includes("@")) {
return false;
}
const parts = email.split("@");
return parts.length === 2 && parts[1].includes(".");
}
console.log(isValidEmail("user@example.com"));
console.log(isValidEmail("invalid"));
2. تنسيق السعر مع العملة
function formatPrice(price, currency = "EGP") {
const symbols = {
EGP: "ج.م",
USD: "$",
EUR: "€"
};
return `${price.toLocaleString()} ${symbols[currency] || currency}`;
}
console.log(formatPrice(1500));
console.log(formatPrice(99.99, "USD"));
3. حساب الخصم الديناميكي
function calculateDiscount(price, quantity) {
let discount = 0;
if (quantity >= 10) discount = 0.2;
else if (quantity >= 5) discount = 0.1;
else if (quantity >= 3) discount = 0.05;
const finalPrice = price * quantity * (1 - discount);
return {
original: price * quantity,
discount: discount * 100 + "%",
final: finalPrice.toFixed(2)
};
}
console.log(calculateDiscount(100, 12));
🚀 الخطوة التالية: المصفوفات المتقدمة
في الدرس السادس، ستتعلم:
- 📦 Methods المصفوفات: push, pop, shift, unshift, splice
- 🔍 البحث: find, findIndex, includes
- 🔄 التحويل: map, filter, reduce بعمق
- 📊 الفرز: sort مع compare functions