انتقل إلى المحتوى

٢.٤ النطاق في JavaScript

النطاق العام

التمرين 1: صرّح عن متغير جديد باسم myVarوأسند إليه 100، ثم اعرض myVar في وحدة التحكم.

var myVar = 100;
console.log(myVar);

النتيجة هي: 100

التمرين 2: أنشئ دالة جديدة تعرض قيمة myVar، ولا تنسَ استدعاءها.

var myVar = 100;

function displayVar(){
  console.log(myVar);
}

displayVar();

النتيجة هي: 100

كيف تعمل الشيفرة السابقة؟

  1. يجهّز محرّك JavaScript التصريحات قبل التنفيذ.
  2. يُعرّف الدالة ويهيّئها displayVar.
  3. يضبط myVar على undefined.
  4. ثم ينفّذ المحرّك التعليمات سطرًا بسطر.
  5. يُسنِد 100 إلى myVar.
  6. ينفّذ تعليمات الدالة ويعرض 100 في وحدة التحكم.

كما ترى، المتغير myVar مُعرّف في المستوى الرئيسي للشيفرة. استطعنا الوصول إلى قيمته myVar من داخل displayVar ؟

النطاق

النطاق يحدّد المواضع التي يمكن الوصول منها إلى متغير في الشيفرة.

النطاق العام

النطاق العام هو النطاق الخارجي الذي يمكن الوصول إلى متغيراته من النطاقات الداخلية، ما لم يحجبها متغير محلي بالاسم نفسه.

التمرين 3: تأمّل الشيفرة وحاول فهم النتيجة.

displayVar();

function displayVar(){
   console.log(myVar);  
}

var myVar = 100;

النتيجة هي: undefined

كيف تعمل الشيفرة السابقة؟

  1. يجهّز محرّك JavaScript التصريحات قبل التنفيذ.
  2. يُعرّف الدالة ويهيّئها displayVar.
  3. يضبط myVar على undefined.
  4. ثم ينفّذ المحرّك التعليمات سطرًا بسطر.
  5. يستدعي الدالة displayVar، وتعرض undefined في وحدة التحكم
  6. يُسنِد 100 إلى myVar.

التمرين 4: ارجع إلى التمرين 3؛ هل myVar مُعرّف في النطاق العام؟

نعم، myVar مُعرّف في النطاق العام ومتاح من داخل الدوال في مثالنا.

التمرين 5: صرّح عن متغير باسم username في النطاق العام. صِل إليه واعرضه داخل دالة.

var username = "Nawras";

function displayUsername(){
  console.log(username);
}

displayUsername();

ستكون النتيجة: Nawras

ملاحظة

يمكن الوصول إلى متغيرات النطاق العام من داخل الدوال.

التمرين 6: تأمّل الشيفرة وافهم النتيجة.

function displayVar(){
   console.log(myVar);
}

var myVar = 100;
displayVar();

ستكون النتيجة: 100

كيف تعمل الشيفرة السابقة؟

  1. يجهّز محرّك JavaScript التصريحات قبل التنفيذ.
  2. يُعرّف الدالة ويهيّئها displayVar.
  3. يضبط myVar على undefined.
  4. ثم ينفّذ المحرّك الشيفرة سطرًا بسطر.
  5. يُسنِد 100 إلى myVar.
  6. يستدعي الدالة displayVar. تعرض 100 في وحدة التحكم.

التمرين 7: ارجع إلى التمرين 6؛ هل myVar مُعرّف في النطاق العام؟

نعم، myVar مُعرّف في النطاق العام ومتاح من داخل الدوال في مثالنا.

النطاق المحلي

التمرين 8: تأمّل الشيفرة وافهم النتيجة.

function setUsername(){
  var username = "Ali";
}

setUsername();
console.log(username);

النتيجة هي: Uncaught ReferenceError: username is not defined

كيف تعمل الشيفرة السابقة؟

  1. يجهّز محرّك JavaScript التصريحات قبل التنفيذ.
  2. يُعرّف الدالة ويهيّئها setUsername.
  3. ثم ينفّذ المحرّك الشيفرة سطرًا بسطر.
  4. يستدعي الدالة setUsername.
  5. يُسنِد "Ali" إلى username. المتغير username متاح فقط داخل الدالة setUsername.
  6. يحاول الوصول إلى username خارج الدالة، لكنه يفشل. لماذا؟

متغيرات النطاق المحلي

المتغيرات المحلية للدالة تُعرَّف داخلها، وتكون متاحة ضمن نطاقها.

ملاحظة

لا يمكنك الوصول مباشرةً إلى متغيرات الدالة المحلية من خارجها.

التمرين 9: تأمّل الشيفرة وافهم النتيجة.

displayHello("Nawras");
console.log(greet);

function displayHello(name){
  var greet  = "Hello " + name;
}

النتيجة هي: Uncaught ReferenceError: greet is not defined

كيف تعمل الشيفرة السابقة؟

  1. يجهّز محرّك JavaScript التصريحات قبل التنفيذ.
  2. يُعرّف الدالة ويهيّئها displayHello.
  3. ثم ينفّذ المحرّك الشيفرة سطرًا بسطر.
  4. يستدعي الدالة displayHello() بالقيمة "Nawras".
  5. يُسنِد "Hello Nawras" إلى greet. المتغير greet متاح فقط داخل الدالة displayHello().
  6. يحاول الوصول إلى greet خارج الدالة، لكنه يفشل لأن المتغير greet محلي للدالة displayHello

ملاحظة

نطاق المتغير greet يُسمّى أيضًا نطاق الدالة، لأنه متاح داخلها فقط.

التمرين 10: تأمّل الشيفرة وافهم النتيجة.

function setUsername(){
  var username = "Ali";
  console.log(username);
}

var username = "Nawras";


console.log(username);
setUsername();
console.log(username);

النتيجة كما يلي:

Nawras
Ali
Nawras

كيف تعمل الشيفرة السابقة؟

  1. يجهّز محرّك JavaScript التصريحات قبل تنفيذ التعليمات.
  2. يُعرّف الدالة ويهيّئها setUsername.
  3. يُسنِد undefined إلى المتغير username.
  4. ثم ينفّذ المحرّك التعليمات سطرًا بسطر.
  5. يُسنِد "Nawras" إلى username.
  6. يبحث عن متغير باسم username في النطاق العام.
  7. يعرض قيمة المتغير العام username، وهي "Nawras".
  8. يستدعي الدالة setUsername().
  9. يُسنِد "Ali" إلى المتغير المحلي username.
  10. console.log(username): يبحث عن username في نطاق الدالة، ويجد username = "Ali"، فتظهر "Ali".
  11. يبحث عن متغير باسم username في النطاق العام.
  12. يعرض قيمة المتغير العام username، وهي "Nawras".

سلسلة النطاقات

عند استخدام متغير، يبحث المحرّك عنه بدءًا من أقرب نطاق.

يبدأ البحث في النطاق المحلي، ثم يتدرّج إلى النطاقات الخارجية حتى النطاق العام. إذا لم يجد المتغير، يحدث ReferenceError.

تُسمّى هذه العملية سلسلة النطاقات.

التمرين 11: ما نتيجة الشيفرة التالية؟

function multiplyByTwo(num){
  var result = num * 2;
  console.log(result);
}

var result = 5;

console.log(result);
multiplyByTwo(6);

النتيجة كما يلي:

5
12

التمرين 12: ارجع إلى التمرين 11؛ لماذا يظهر 5 أولًا؟

تبحث JavaScript عن المتغير result في أقرب نطاق، وهو هنا النطاق العام. وفيه result قيمته 5.

التمرين 13: ارجع إلى التمرين 11؛ لماذا يظهر 12 ثانيًا؟

تبحث JavaScript عن المتغير result في أقرب نطاق، وهو نطاق الدالة. وفيه result قيمته 12.

التمرين 14: ما نتيجة الشيفرة التالية؟

function multiplyByTwo(num){
  console.log(result);
}

var result = 5;

console.log(result);
multiplyByTwo(6);

النتيجة كما يلي:

5
5

التمرين 15: ارجع إلى التمرين 14؛ لماذا يظهر 5 أولًا؟

تبحث JavaScript عن المتغير result في أقرب نطاق، وهو هنا النطاق العام. وفيه result قيمته 5.

التمرين 16: ارجع إلى التمرين 14؛ لماذا يظهر 5 ثانيًا؟

تبحث JavaScript عن المتغير result في أقرب نطاق، وهو نطاق الدالة. وفيه result غير مُعرّف، فتبحث عن result في النطاق العام. وفيه result قيمته 5.

سنتعلّم عن نطاق الكتلة (Block) و والنطاق المعجمي (Lexical) لاحقًا في الدورة.