جاري التحميل...
جاري التحميل...
if/else، الدوال التقليدية والسهمية، النطاق، الأغلاقات
في هذا الدرس سنتعلم ثلاثة مفاهيم أساسية في جافاسكريبت تشكل الأساس لكل برنامج تفاعلي:
💡 تشبيه بسيط::
تخيل أنك مدير مطعم. الجمل الشرطية مثل قواعد خدمة العملاء (إذا كان العميل وحده، أعطه طاولة صغيرة؛ وإلا أعطه طاولة كبيرة). الدوال مثل إجراءات المطبخ القياسية (وصفة البيتزا تُكتب مرة واحدة والشيف يطبقها كلما طلب عميل). النطاقات مثل مناطق المطعم: ما يحدث في المطبخ يبقى في المطبخ ولا يُسمع في منطقة الطعام.
بدون الجمل الشرطية والدوال، سيكون الكود مجرد سلاسل تعليمات متتالية بدون ذكاء أو تنظيم. إليك الأسباب الرئيسية:
دعنا ننظر إلى مثال مشكلة حقيقية. تخيل أنك تكتب كودًا لحساب خصم على المنتجات:
الكود أعلاه يعمل، لكنه به مشاكل: التكرار، صعوبة التعديل، وخطر الأخطاء. إذا أردت تغيير طريقة حساب الخصم، تحتاج إلى تعديل ثلاثة أماكن!
الحل: استخدام الدوال:
الآن إذا أردت تغيير طريقة الحساب، تعدّلها في مكان واحد فقط!
الجمل الشرطية تسمح للكود بالـ 'تفكير' واتخاذ القرارات. جافاسكريبت تتحقق من شرط: إذا كان صحيحًا، تنفذ كودًا معينًا؛ إذا كان خطأ، تنفذ كودًا آخر أو لا تفعل شيئًا.
1. الشرط الأساسي: if
ينفذ الكود داخل الأقواس فقط إذا كان الشرط صحيحًا:
2. الشرط المزدوج: if / else
إذا لم يتم تلبية الشرط، يُنفذ الكود في كتلة else:
3. سلسلة الشروط: if / else if / else
يمكنك اختبار شروط متعددة بالتسلسل:
💡 ملاحظة مهمة::
جافاسكريبت تتحقق من الشروط من الأعلى إلى الأسفل وتنفذ أول شرط يتم تلبيته فقط، ثم تتوقف. حتى إذا تم تلبية شرط لاحقًا، لن يُنفذ.
4. switch / case
مفيدة عندما تريد مقارنة قيمة مع احتمالات متعددة:
💡 تحذير: لا تنسَ break!:
إذا نسيت break، ستمتد جافاسكريبت عبر جميع الحالات التالية (fall-through) حتى تجد break أو ينتهي switch. هذا عادةً ليس ما تريده.
5. العمليات الثلاثية
اختصار لـ if/else في سطر واحد:
مفيدة للحالات البسيطة، لكن لا تسرف في استخدامها. الشروط المعقدة تُكتب بشكل أفضل باستخدام if/else لوضوح الكود.
الدالة هي حزمة كود يمكنك استدعاؤها في أي وقت. جافاسكريبت لها عدة طرق لتعريف الدوال:
1. تعريف الدالة
الطريقة الكلاسيكية الأكثر شيوعًا. هذه الطريقة تدعم الرفع (سنتحدث عنه لاحقًا):
2. تعبير الدالة
الدالة تُعرَّف كقيمة مخزنة في متغير. هذه الطريقة لا تدعم الرفع:
3. دالة السهم (ES6+)
صياغة مختصرة وحديثة. ستحتاجها كثيرًا عند تعلم React حيث تُستخدم بشكل واسع في المكونات والأحداث:
💡 تحضير لـ React::
دوال السهم تُستخدم بشكل واسع في React لكتابة المكونات الدوال ومعالجات الأحداث. إلمامك بها الآن سيجعل تعلم React أسهل بكثير.
4. مقارنة سريعة بين الأنواع الثلاثة
دعنا نطبق ما تعلمناه في مثال واقعي: نظام تسجيل دخول بسيط يجمع بين الجمل الشرطية والدوال:
💡 ملاحظات على المثال::
استخدمنا دوال صغيرة متخصصة (validateEmail, validatePassword) بدلاً من كتابة كل شيء في دالة كبيرة واحدة. استخدمنا شروط متعددة (if/else if/else) في دالة getGreeting. دالة login تُرجع كائنًا يحتوي على نتيجة التحقق. هذا نمط شائع في جافاسكريبت.
هذه الأجزاء الأكثر أهمية في الدرس. فهمها سيمنعك من الأخطاء المربكة في جافاسكريبت.
1. النطاق - أين يمكن رؤية المتغير؟
النطاق يحدد أين يمكن الوصول إلى متغير أو دالة. هناك ثلاثة أنواع رئيسية:
💡 الفرق الجوهري بين var و let و const::
var: نطاق الدالة فقط - تتجاوز حدود الكتلة { }!let: نطاق الكتلة - محصورة في الكتلة {} التي عُرفت فيها.const: نطاق الكتلة أيضًا - مثل let لكن لا تسمح بإعادة التعيين.
القاعدة: استخدم دائمًا const، استخدم let فقط عندما تحتاج إلى تغيير القيمة، ولا تستخدم var أبدًا في الكود الحديث.
2. النطاق المفاهيمي
3. الإغلاقات (Closures)
الإغلاق يحدث عندما تحتفظ دالة داخلية بمرجع لمتغيرات في نطاقها الخارجي، حتى بعد انتهاء الدالة الخارجية من التنفيذ. ببساطة: الدالة 'تغلّف' المتغيرات معها.
💡 لماذا الإغلاقات مهمة لـ React؟:
في React، Hooks مثل useState وuseEffect تعتمد مباشرة على مفهوم الإغلاقات. كل مرة تكتب فيها const [count, setCount] = useState(0)، دالة setCount تحتفظ بمرجع لحالة count بفضل الإغلاق.
4. الرفع - ماذا يحدث خلف الكواليس
الرفع هو سلوك في جافاسكريبت حيث 'يرفع' المفسر تعريفات المتغيرات والدوال إلى أعلى النطاق قبل تنفيذ الكود. لكن السلوك يختلف حسب الكلمة المفتاحية:
💡 ملخص الرفع::
تعريف الدالة: مرفوع بالكامل (التعريف + المحتوى) - يمكن استدعاؤه قبل التعريف.var: فقط التعريف مرفوع (القيمة = undefined) - لا خطأ لكن القيمة غير معرفة.let / const: غير مرفوعة - محاولة الوصول قبل التعريف تُعطي ReferenceError.تعبير الدالة / دالة السهم: غير مرفوعة - يجب تعريفها قبل الاستدعاء.
var تتجاوز حدود الكتلة وتسبب أخطاء غير متوقعة. استخدم دائمًا const، وlet عندما تحتاج إلى تغيير القيمة.break، ينفذ الكود جميع الحالات التالية حتى يجد break أو ينتهي switch.== تؤدي إلى تحويل نوع قد يُعطي نتائج غير متوقعة مثل 0 == '' يُعطي true. استخدم دائمًا ===.this خاصًا بها (تأخذه من النطاق الخارجي). هذا مفيد في أغلب الأحيان، لكن قد يسبب أخطاء أحيانًا.for، يتم إنشاء نسخة جديدة في كل تكرار. استخدم الإغلاق بشكل صحيح أو دالة خارجية.const كافتراضي، وlet فقط عندما تحتاج إلى تغيير القيمة.calculateTotal وvalidateEmail بدلاً من doStuff أو handleThings.ماذا سيطبع الكود التالي في وحدة التحكم؟
ماذا سيطبع الكود التالي؟
أنشئ دالة <code>calculator</code> تأخذ ثلاثة معاملات: رقمين وعملية رياضية (+, -, *, /). يجب أن تفعل: 1. استخدام شرط switch/case لاختيار العملية، 2. التعامل مع القسمة على صفر (عرض رسالة خطأ)، 3. إرجاع النتيجة. مثال: <code>calculator(10, 5, '+')</code> تُرجع 15
الحل:
function greetUser(name, timeOfDay) {
let greeting;
switch (timeOfDay) {
case "morning":
greeting = "صباح الخير";
break;
case "afternoon":
greeting = "مساء الخير";
break;
case "evening":
greeting = "مساء الخير";
break;
default:
greeting = "مرحباً";
}
return `${greeting}, ${name}!`;
}
console.log(greetUser("أحمد", "morning"));
console.log(greetUser("فاطمة", "evening"));
function calculateGrade(score) {
if (score >= 90) return "ممتاز";
if (score >= 80) return "جيد جداً";
if (score >= 70) return "جيد";
if (score >= 60) return "مقبول";
return "راسب";
}
const scores = [95, 82, 67, 45, 88];
scores.forEach(score => {
console.log(`الدرجة: ${score} - التقدير: ${calculateGrade(score)}`);
});
function factorial(n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
console.log("م factorial(5):", factorial(5));
function isEven(num) {
return num % 2 === 0;
}
console.log("هل 7 زوجي؟", isEven(7));
console.log("هل 10 زوجي؟", isEven(10));أنشئ برنامجًا:
💡 اجمع مفاهيم if-else و switch والدوال.
الجمل الشرطية:
if (condition) {"{}"} - ينفذ الكتلة إذا كان الشرط صحيحًاelse if (condition) {"{}"} - شرط بديلelse {"{}"} - الكتلة الافتراضيةswitch (value) {"{}"} - مطابقة حالات متعددةالدوال:
function name() {"{}"} - تعريف الدالة (مرفوعة)const name = () => {} - دالة السهمreturn value - إرجاع من الدالة