📌 النطاق (Scope) في دوال Dart

النطاق (Scope) في Dart يحدد مكان الوصول إلى المتغيرات، سواء داخل دالة أو خارجها.
يُقسم النطاق إلى عدة أنواع رئيسية:

  1. النطاق العام (Global Scope)
  2. النطاق المحلي (Local Scope)
  3. نطاق الدوال المتداخلة (Nested Function Scope)
  4. نطاق الكتلة (Block Scope)
  5. نطاق المعاملات (Parameter Scope)

📌 دعونا نوضح كل نوع بالتفصيل مع الأمثلة! 👇


🔹 1. النطاق العام (Global Scope)

🔹 المتغيرات المعرّفة خارج أي دالة تكون عالمية، ويمكن الوصول إليها من أي مكان داخل الملف.

✨ مثال: متغير عام (Global Variable)

String globalMessage = 'أنا متغير عام!'; // متغير عالمي

void printMessage() {
  print(globalMessage); // يمكن الوصول إليه داخل أي دالة
}

void main() {
  printMessage(); // ✅ صحيح
  print(globalMessage); // ✅ صحيح
}
Dart

🔹 الناتج:

نسختحريرأنا متغير عام!
أنا متغير عام!

📌 المتغير globalMessage متاح في أي مكان داخل الملف.


🔹 2. النطاق المحلي (Local Scope)

🔹 المتغيرات المعرّفة داخل دالة تكون محلية، ولا يمكن الوصول إليها من خارج الدالة.

✨ مثال: متغير محلي (Local Variable)

void showMessage() {
  String message = 'أنا متغير محلي داخل الدالة!';
  print(message);
}

void main() {
  showMessage(); // ✅ صحيح
  // print(message); // ❌ خطأ - المتغير غير متاح خارج الدالة
}
Dart

🔹 الناتج:

📌 المتغير message متاح فقط داخل showMessage().


🔹 3. نطاق الدوال المتداخلة (Nested Function Scope)

🔹 في Dart، يمكن تعريف دالة داخل دالة أخرى، وتكون الدالة الداخلية قادرة على الوصول إلى المتغيرات في الدالة الخارجية، ولكن العكس غير صحيح.

✨ مثال: دوال متداخلة (Nested Functions)

void outerFunction() {
  String outerMessage = 'أنا داخل الدالة الخارجية';

  void innerFunction() {
    print(outerMessage); // ✅ يمكن الوصول للمتغير من الدالة الخارجية
  }

  innerFunction(); // استدعاء الدالة الداخلية
}

void main() {
  outerFunction(); // ✅ صحيح
  // innerFunction(); // ❌ خطأ - لا يمكن استدعاؤها مباشرة
}
Dart

🔹 الناتج:

📌 الدالة innerFunction() تستطيع الوصول إلى outerMessage، ولكن لا يمكن استدعاؤها خارج outerFunction().


🔹 4. نطاق الكتلة (Block Scope)

🔹 المتغيرات المعرّفة داخل {} تكون محصورة داخلها فقط، ولا يمكن الوصول إليها خارجها.

✨ مثال: نطاق الكتلة (Block Scope)

void main() {
  if (true) {
    String blockMessage = 'أنا داخل كتلة if';
    print(blockMessage);
  }

  // print(blockMessage); // ❌ خطأ - لا يمكن الوصول للمتغير خارج الكتلة
}
Dart

🔹 الناتج:

📌 المتغير blockMessage متاح فقط داخل {} الخاصة بـ if.


🔹 5. نطاق المعاملات (Parameter Scope)

🔹 المعاملات الممررة إلى دالة تكون متاحة فقط داخلها ولا يمكن استخدامها خارجها.

✨ مثال: نطاق المعاملات (Parameter Scope)

void greet(String name) {
  print('مرحبًا، $name!');
}

void main() {
  greet('Ali'); // ✅ صحيح
  // print(name); // ❌ خطأ - لا يمكن الوصول إلى "name" خارج الدالة
}
Dart

🔹 الناتج:

نسختحريرمرحبًا، Ali!

📌 name متاح فقط داخل greet().


🔹 الفرق بين النطاقات المختلفة

النوعمتاح داخلمتاح خارج
نطاق عام (Global Scope)كل الدوال والكتل✅ نعم
نطاق محلي (Local Scope)الدالة المعرّف بها المتغير❌ لا
نطاق دوال متداخلة (Nested Scope)الدالة الداخلية❌ لا خارج الدالة الأم
نطاق كتلة (Block Scope)داخل {} فقط❌ لا
نطاق المعاملات (Parameter Scope)داخل الدالة فقط❌ لا

🔹 الخلاصة

✅ المتغيرات العامة (Global Variables) متاحة في كل مكان داخل الملف.
✅ المتغيرات المحلية (Local Variables) متاحة فقط داخل الدالة المعرّفة بها.
✅ الدوال المتداخلة (Nested Functions) يمكنها الوصول إلى متغيرات الدالة الخارجية.
✅ المتغيرات داخل {} (مثل if, for, while) متاحة فقط داخل نفس الكتلة (Block Scope).
✅ المعاملات (Parameters) متاحة فقط داخل الدالة الممررة إليها.