JavaScript: الدوال في جافاسكريبت
آخر تحديث: 2026-10-13
الدوال هي كتلة كود قابلة لإعادة الاستخدام — اكتبها مرة واحدة، واستخدمها بلا نهاية. فكّر فيها كوصفات: حدد الخطوات مرة واحدة، ثم اتبعها كلما طبخت. مبرمج لا يستخدم الدوال مثل شخص يخترع كل طبق من الصعب — مُرهق وعرضة للأخطاء.
1. ما هي الدالة؟
الدالة "تُغلّف" قطعة منطق، تعطيها اسمًا، وتتيح لك استدعائها متى احتجت:
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head><meta charset="UTF-8"><title>استدعاء الدوال</title></head>
<body>
<div id="output"></div>
<script>
function sayHello() {
document.getElementById('output').textContent += 'مرحبا!\n';
}
sayHello();
sayHello();
</script>
</body>
</html>
فوائد الدوال:
- قابلية إعادة الاستخدام: اكتب مرة واحدة، استدعِ في كل مكان
- التغليف: خفِّ التعقيد، اعرض فقط الواجهة
- قابلية الصيانة: غيّرها في مكان واحد، كل مستفيد يستفيد
2. إعلان الدالة مقابل تعبير الدالة
هناك طريقتان رئيسيتان لإنشاء الدوال:
<script>
// إعلان الدالة
function greet(name) {
return `مرحبا، ${name}!`;
}
// تعبير الدالة
let greet2 = function(name) {
return `مرحبا، ${name}!`;
};
</script>
الفرق الرئيسي: إعلانات الدوال تُرفع — يمكنك استدعائها قبل ظهورها في الكود. تعبيرات الدوال لا تُرفع; يجب تعريفها أولاً.
<script>
// إعلان الدالة: استدعاء قبل التعريف — يعمل بشكل جيد
hello(); // يعمل بدون خطأ
function hello() { console.log('مرحبا'); }
// تعبير الدالة: استدعاء قبل التعريف — خطأ
// hi(); // TypeError: hi is not a function
// let hi = function() { console.log('مرحبا'); };
</script>
let قبل إعلانه يُطلق خطأ "المنطقة الزمنية الميتة" (TDZ) — وليس undefined. لذلك عرّف دائمًا تعبيرات الدوال قبل استخدامها.
3. المعلمات والمعاملات الافتراضية
تقبل الدوال البيانات الخارجية عبر المعلمات:
<script>
function add(a, b) {
return a + b;
}
add(1, 2); // 3
</script>
المعلمات التي لا تمررها تكون undefined. قدم ES6 المعلمات الافتراضية:
<script>
function greet(name, greeting = 'مرحبا') {
return `${greeting}، ${name}!`;
}
greet('سارة'); // 'مرحبا، سارة!'
greet('سارة', 'أهلا'); // 'أهلا، سارة!'
</script>
4. القيم المُرجعة
return تُرسل نتيجة إلى المتصل وتوقف الدالة فورًا:
<script>
function square(n) {
return n * n;
}
let result = square(5); // 25
</script>
دالة بدون return (أو مع return; فقط) تُرجع undefined.
<script>
function doNothing() {
// لا يوجد return
}
doNothing(); // undefined
</script>
return يسبب إدخال نقطة فاصلة تلقائي، مما يجعلها تُرجع undefined:
return // يصبح: return; undefined
obj; // هذا السطر لا يُنفذ أبدًا
الحل: احتفظ بالقيمة المُرجعة على نفس السطر، أو لفّها بأقواس.
5. الدوال السهمية (=>)
الدوال السهمية هي بنية أقصر قُدمت في ES6:
<script>
// دالة عادية
let double = function(n) {
return n * 2;
};
// دالة سهمية
let double2 = (n) => n * 2;
// جمل متعددة تتطلب أقواسًا وreturn صريح
let greet = (name) => {
let msg = `مرحبا، ${name}!`;
return msg;
};
</script>
قواعد البناء:
- معلمة واحدة: الأقواس اختيارية —
n => n * 2 - صفر أو عدة معلمات: الأقواس مطلوبة —
() => 'مرحبا'،(a, b) => a + b - تعبير سطر واحد: يُرجع تلقائيًا; multi-line: يحتاج
{}+return
▶ مثال: استخدام الدوال الأساسي
▶ جرّب الكود▶ مثال: حاسبة بسيطة
▶ جرّب الكود6. نطاق الدالة
المتغيرات المعلنة داخل دالة محلية — ت tồnيد فقط داخل تلك الدالة. هذا هو النطاق:
<script>
function test() {
let x = 10; // متغير محلي
const y = 20;
var z = 30;
}
test();
// console.log(x); // ReferenceError: x is not defined
</script>
يمكن للدوال الوصول إلى المتغيرات الخارجية (أساس الإغلاق)، لكن الكود الخارجي لا يمكنه الوصول إلى المتغيرات داخل الدالة:
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head><meta charset="UTF-8"><title>نطاق الدالة</title></head>
<body>
<pre id="output"></pre>
<script>
let global = 'متغير عام';
function show() {
let local = 'متغير محلي';
document.getElementById('output').textContent +=
'داخل الدالة — global: ' + global + '\n' +
'داخل الدالة — local: ' + local + '\n';
}
show();
document.getElementById('output').textContent +=
'خارج الدالة — global: ' + global + '\n' +
'خارج الدالة — local: غير قابل للوصول (متغير محلي)';
</script>
</body>
</html>
let/const/var يُنشئ متغيرًا عامًا — مصدر شائع للأخطاء. أعلن دائمًا المتغيرات بـ let أو const.
▶ مثال: عرض النطاق
▶ جرّب الكود7. مقدمة في الاستدعاءات الخلفية
جافاسكريبت تتيح لك تمرير دالة كوسيط لدالة أخرى — الدالة المُمرَّرة تسمى استدعاء خلفي:
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head><meta charset="UTF-8"><title>الاستدعاءات الخلفية</title></head>
<body>
<pre id="output"></pre>
<script>
function processArray(arr, callback) {
for (let item of arr) {
callback(item);
}
}
let names = ['سارة', 'أحمد', 'محمد'];
processArray(names, function(name) {
document.getElementById('output').textContent += 'مرحبا، ' + name + '\n';
});
</script>
</body>
</html>
لقد استخدمت بالفعل الاستدعاءات الخلفية — وسائط forEach وmap وfilter كلها دوال استدعاء خلفي:
<script>
// الدالة المجهولة هنا هي استدعاء خلفي
[1, 2, 3].forEach(function(n) {
console.log(n);
});
// الدوال السهمية تجعلها أكثر اختصارًا
[1, 2, 3].forEach(n => console.log(n));
</script>
▶ مثال: الاستدعاءات الخلفية في العمل
▶ جرّب الكود❓ أسئلة شائعة
this الخاص بها — تُرثه من النطاق المحيط. عندما تحتاج this للإشارة إلى الكائن الحالي (في الأساليب أو معالجات الأحداث)، استخدم دالة عادية. للدوال البسيطة المساندة، بنية السهم تعمل بشكل رائع.function getInfo() { return [name, age]; } — ثم استدعِ بـ let [name, age] = getInfo().function createUser({ name, age, city }) {} — استدعِه بـ createUser({ name: 'سارة', age: 20, city: 'القاهرة' }). الترتيب لا يهم، وهو أكثر قراءة بكثير.📖 ملخص
- إعلانات الدوال تُرفع; تعبيرات الدوال لا تُرفع — التعريف قبل الاستخدام هو الأسلم
- المعلمات الافتراضية تضيف مرونة; ضعها في نهاية قائمة المعلمات
returnتنهي الدالة وتعيد قيمة; بدونها، تُرجع الدالةundefined- الدوال السهمية
(a, b) => a + bهي اختصار — سطر واحد يُرجع تلقائيًا، multi-line يحتاج `{}`` - المتغيرات المعلنة داخل دالة محلية وغير مرئية من الخارج
- الاستدعاءات الخلفية = تمرير دالة كوسيط — تُستخدم بواسطة
forEachوsetTimeoutوالمزيد
📝 تمارين
- أساسي (الصعوبة ⭐): اكتب دالة
greet(name)تعيد "Hello, [name]!". اختبرها مع 3 أسماء مختلفة. - متوسط (الصعوبة ⭐⭐): أنشئ دالة
sum(a, b, ...rest)تقبل أي عدد من الوسائط وتعيد مجموعها. استخدم معامل الباقي. - تحدي (الصعوبة ⭐⭐⭐): أنشئ دالة
factorial(n)تحسب المضروب بشكل تكراري. أضف التحقق من المدخلات.