| النطاق | أين يُعرَّف | الوصول إليه |
|---|---|---|
| Global Scope | خارج أي دالة أو كتلة | من أي مكان في البرنامج |
| Function Scope | داخل دالة (var) | داخل الدالة فقط |
| Block Scope | داخل {} (let/const) | داخل تلك الكتلة فقط |
النطاق (Scope) يُحدد أين في الكود يمكن الوصول إلى متغير معين. يوجد نوعان أساسيان: النطاق العام (Global Scope) للمتغيرات المُعرَّفة خارج أي دالة أو كتلة، ويمكن الوصول إليها من أي مكان في البرنامج بالكامل. والنطاق المحلي (Local Scope) للمتغيرات المُعرَّفة داخل دالة أو كتلة معينة، ولا يمكن الوصول إليها من خارجها.
مع let وconst، يوجد نطاق أدق يُسمى نطاق الكتلة (Block Scope) — أي متغير مُعرَّف داخل أي أقواس {} (سواء دالة، شرط if، أو حلقة) يكون محصوراً داخلها فقط ولا يتسرب خارجها. هذا يختلف عن var التي كانت تتجاهل نطاق الكتلة وتلتزم فقط بنطاق الدالة، وهو ما كان يُسبب أخطاء خفية شهيرة في الكود القديم.
مفهوم "سلسلة النطاق" (Scope Chain) يعني أن أي دالة داخلية يمكنها الوصول لمتغيرات النطاقات المحيطة بها (الدالة الأب، ثم النطاق العام)، لكن العكس غير صحيح — النطاق الخارجي لا يمكنه أبداً الوصول لمتغيرات معرَّفة داخل نطاق أدق منه.
من أفضل الممارسات البرمجية تقليل استخدام المتغيرات العامة (Global Variables) قدر الإمكان، لأنها تجعل تتبع من يُعدّل القيمة ومتى أمراً صعباً جداً في البرامج الكبيرة، وقد تُسبب تعارضاً بين أجزاء مختلفة من الكود تستخدم نفس الاسم بالخطأ. الأفضل هو حصر المتغيرات داخل أضيق نطاق ممكن يحتاجها فعلاً.
| 1 | let متغير_عام = "أراني الجميع"; // Global Scope |
| 2 | |
| 3 | function دالة() { |
| 4 | let متغير_محلي = "أراني فقط هنا"; // Local/Function Scope |
| 5 | console.log(متغير_عام); // ✅ يعمل: يصل للنطاق العام |
| 6 | } |
| 7 | |
| 8 | // console.log(متغير_محلي); // ❌ خطأ: غير معرّف هنا |
مثال 1: الفرق بين let و var في نطاق الكتلة
| 1 | // نطاق الكتلة block scope مع let |
| 2 | if (true) { |
| 3 | let محلي = "داخل الشرط"; |
| 4 | var قديم = "خارج نطاق الكتلة"; |
| 5 | } |
| 6 | // console.log(محلي); // ❌ خطأ: محصور داخل if |
| 7 | console.log(قديم); // ✅ "خارج نطاق الكتلة" — var تتجاهل block scope |
مثال 2: سلسلة النطاق (Scope Chain)
| 1 | // سلسلة النطاق Scope Chain |
| 2 | let مستوى1 = "أ"; |
| 3 | function خارجية() { |
| 4 | let مستوى2 = "ب"; |
| 5 | function داخلية() { |
| 6 | let مستوى3 = "ج"; |
| 7 | // الدالة الداخلية ترى كل المستويات الخارجية |
| 8 | console.log(مستوى1, مستوى2, مستوى3); |
| 9 | } |
| 10 | داخلية(); |
| 11 | } |
| 12 | خارجية(); // "أ ب ج" |