النطاق مفهوم مهم في تحديد مدى توفر المتغيرات. يقع هذا المفهوم في صميم عمليات الإغلاق ، حيث يقسم المتغيرات إلى عالمية ومحلية.
سأحاول في هذه المقالة أن أشرح بعبارات بسيطة النطاق الموجود في JavaScript.
1 نطاق
قبل الغوص في تفاصيل النطاق ، دعنا نلقي نظرة على مثال سريع.
لنفترض أننا حددنا متغيرًا:
const message = 'Hello'
console.log(message) // 'Hello'
يمكننا بسهولة إخراج قيمته إلى وحدة التحكم. هذا واضح.
الآن لنضع إعلان متغير الرسالة في كتلة if:
if (true) {
const message = 'Hello'
}
console.log(message) // ReferenceError: message is not defined
هذه المرة ، عند محاولة الوصول إلى المتغير ، يتم طرح خطأ ReferenceError: لم يتم تعريف رسالة استثناء.
لماذا حدث هذا؟
لأن كتلة if قد أنشأت نطاقًا لمتغير الرسالة. والرسالة متاحة فقط ضمن هذا النطاق.
وبالتالي ، فإن توافر المتغيرات مقيد بالنطاق الذي يتم تحديدها فيه.
لذا فإن النطاق هو نطاق المتغيرات.
2. كتلة النطاق
تحدد كتلة التعليمات البرمجية في JavaScript نطاق المتغيرات المعلنة باستخدام الثابت والسماح للكلمات الرئيسية:
if (true) {
// if
const message = 'Hello'
console.log(message) // 'Hello'
}
console.log(message) // ReferenceError
يقوم أول console.log () بطباعة قيمة متغير الرسالة بأمان إلى وحدة التحكم ، حيث يتم الوصول إلى هذا المتغير في النطاق الذي تم تعريفه فيه.
ومع ذلك ، يؤدي استدعاء console.log () الثاني إلى حدوث خطأ لأن متغير الرسالة غير متاح في نطاقه الخارجي: الرسالة غير موجودة في السياق الحالي.
يتم أيضًا إنشاء نطاق الكتلة في عبارات if و for و while.
على سبيل المثال:
for (const color of ['green', 'red', 'blue']) {
// for
const message = 'Hi'
console.log(color) // 'green', 'red', 'blue'
console.log(message) // 'Hi', 'Hi', 'Hi'
}
console.log(color) // ReferenceError
console.log(message) // ReferenceError
متغيرات اللون والرسالة موجودة فقط داخل كتلة for.
وينطبق الشيء نفسه على بيان while:
while (/* */) {
// while
const message = 'Hi'
console.log(message) // 'Hi'
}
console.log(message) // ReferenceError
الرسالة المحددة في حين متاحة فقط داخل هذه الحلقة.
في JavaScript ، يمكنك إنشاء كتل من التعليمات البرمجية قائمة بذاتها. يحددون أيضًا نطاقهم الخاص:
{
const message = 'Hi'
console.log(message) // 'Hi'
}
console.log(message) // ReferenceError
2.1. var ليس نطاقًا محددًا
كما رأينا في الأمثلة السابقة ، تخلق كتلة من التعليمات البرمجية مجالًا للمتغيرات التي تم الإعلان عنها باستخدام الثابت و let. ومع ذلك ، هذا لا يعمل مع المتغيرات التي تم التصريح عنها باستخدام كلمة var.
لنفكر في مثال:
if (true) {
// if
var count = 0
console.log(count) // 0
}
console.log(count) // 0
العدد المتغير متاح داخل كتلة if ، كما هو متوقع. ومع ذلك ، فهو متاح أيضًا خارج هذه الكتلة!
النقطة المهمة هي أن كتلة التعليمات البرمجية لا تُنشئ مجالًا للمتغيرات المُعلنة باستخدام كلمة var. لكن الوظيفة تفعل ذلك.
3. نطاق الوظيفة
تعمل الوظائف في JavaScript على إنشاء نطاق لجميع المتغيرات ، بغض النظر عن الكلمة الأساسية التي يتم الإعلان عنها بها (var أو const أو let).
على سبيل المثال:
function run() {
// run()
var message = ', , !'
console.log(message)
}
run() // ', , !'
console.log(message) // ReferenceError
تُنشئ الدالة run () نطاقًا. الرسالة المتغيرة متاحة داخل الوظيفة ، ولكن ليس خارجها.
وبالمثل ، تُنشئ الوظيفة نطاقًا للمتغيرات المُعلنة بـ const و let ، وحتى لوظائف أخرى وتعبيرات وظيفية:
function run() {
// run()
const two = 2
let one = 1
function run2() {}
var run3 = () => {}
console.log(two)
console.log(one)
console.log(run2)
console.log(run3)
}
run() // 2 1 ƒ run2() {} () => {}
console.log(two) // ReferenceError
console.log(one) // ReferenceError
console.log(run2) // ReferenceError
console.log(run3) // ReferenceError
4. وحدة الرؤية
تنشئ وحدات ES6 أيضًا مجالًا للمتغيرات والوظائف والفئات.
وحدة الدائرة تنشئ pi ثابتًا (للاستخدام الداخلي):
// circle
const pi = 3.14
console.log(pi) // 3.14
// pi
يتم الإعلان عن متغير pi داخل وحدة الدائرة ولا يتم تصديره من هناك.
ثم يتم استيراد وحدة الدائرة:
import './circle'
console.log(pi) // ReferenceError
لا يتوفر المتغير pi خارج وحدة الدائرة (حتى يتم تصديره باستخدام التصدير).
النطاق المعياري يغلف الوحدات. هذا يعني أن المتغيرات الخاصة (التي لم يتم تصديرها) تُستخدم لاحتياجات الوحدة الخاصة وتتم حمايتها من الوصول الخارجي.
وبالتالي ، يمكننا القول أن النطاق عبارة عن آلية تغليف لكتل من التعليمات البرمجية والوظائف والوحدات النمطية.
5. يمكن أن تكون النطاقات متداخلة
ميزة مثيرة للاهتمام للنطاقات هي أنها يمكن أن تتداخل مع بعضها البعض.
في المثال التالي ، تُنشئ الدالة run () نطاقًا ، وداخلها ، تُنشئ كتلة if نطاقًا آخر:
function run() {
// run()
const message = ', , !'
if (true) {
// if
const friend = ''
console.log(message) // ', , !'
}
console.log(friend) // ReferenceError
}
run()
نطاق كتلة if متداخل في نطاق الدالة run ().
النطاق الموجود داخل نطاق آخر يسمى النطاق الداخلي. في المثال أعلاه ، هذا هو نطاق كتلة if.
النطاق الذي يحتوي على نطاق آخر يسمى النطاق الخارجي. في المثال أعلاه ، هذا هو نطاق وظيفة run ().
ماذا عن التوافر المتغير؟ هناك قاعدة بسيطة يجب تذكرها:
المتغيرات من النطاق الخارجي متوفرة في النطاق الداخلي.
لذلك ، يتوفر متغير الرسالة داخل كتلة if.
6. النطاق العالمي
النطاق العالمي هو النطاق الخارجي. وهي متاحة لأي نطاق داخلي أو محلي. في المستعرض ، يتم إنشاء النطاق العام عندما يتم تحميل ملف JavaScript المحدد في السمة src لعلامة البرنامج النصي:
<script src="script.js">
// script.js
// global domain
let counter = 1
المتغيرات المعلنة في النطاق العام هي متغيرات عالمية. كانت متوفرة في أي منطقة أخرى.
النطاق العام هو آلية تسمح لوقت تشغيل JavaScript (المتصفح ، Node.js) بتعريض الكائنات المضيفة (أي المملوكة للبيئة) للتطبيقات كمتغيرات عامة.
على سبيل المثال ، تعد النافذة والمستند متغيرات عامة (كائنات) يوفرها المتصفح. في Node.js ، يكون هذا المتغير ، على سبيل المثال ، كائن العملية.
7. النطاق المعجمي
دعنا نحدد وظيفتين ، إحداهما متداخلة في الأخرى:
function outer() {
// outer()
let v = ' outer()!'
function inner() {
// inner()
console.log(v) // ' outer()!'
}
return inner
}
const f = outer()
f()
ألقِ نظرة على السطر الأخير: يُسمى الداخلي () خارج نطاق الخارجي (). كيف تعرف JavaScript أن القيمة المطبوعة على وحدة التحكم في الوظيفة الداخلية () تنتمي إلى المتغير v المُعلن في الدالة () الخارجية؟
الجواب: بفضل النطاق المعجمي.
تنفذ JavaScript آلية تسمى تحديد النطاق المعجمي أو الثابت. النطاق المعجمي يعني أن إمكانية الوصول إلى المتغيرات يتم تحديدها بشكل ثابت من خلال موضع هذه المتغيرات داخل نطاق الوظيفة المتداخلة: المتغيرات من نطاق الوظيفة الخارجية متوفرة في نطاق الوظيفة المتداخلة.
التعريف الرسمي للنطاق المعجمي هو كما يلي:
يتكون النطاق المعجمي من نطاقات خارجية محددة بشكل ثابت ، أي من المناطق الخارجية ، ثابتة باستخدام متغيرات من تلك المناطق في الوظائف الداخلية.
في المثال أعلاه ، يتكون النطاق المعجمي للوظيفة الداخلية () من نطاق الوظيفة الخارجية ().
علاوة على ذلك ، يعد الجزء الداخلي () إغلاقًا لأنه يستخدم قيمة المتغير من النطاق المعجمي.
8. عزل المتغيرات
من الواضح أن النطاق يعزل المتغيرات. هذا يسمح للنطاقات المختلفة أن تحتوي على متغيرات بنفس الاسم.
يمكنك استخدام عدد المتغيرات ، والفهرس ، والتيار ، والقيمة ، إلخ. في مناطق مختلفة دون التعرض لخطر الاصطدام (تعارض الأسماء).
على سبيل المثال:
function foo() {
// foo()
let count = 1
console.log(count) // 1
}
function bar() {
// bar()
let count = 2
console.log(count) // 2
}
foo()
bar()
خاتمة
النطاق يحدد مدى توافر المتغيرات. المتغير المعلن في النطاق الحالي متاح فقط داخله.
في JavaScript ، يتم إنشاء النطاقات بواسطة الكتل والوظائف والوحدات النمطية.
يمكن أن تكون المتغيرات المعلنة باستخدام الثابت والسماح للكلمات الرئيسية كتلة أو وظيفية أو معيارية ، في حين أن المتغيرات التي تم الإعلان عنها باستخدام كلمة var ليست محددة النطاق.
يمكن أن تتداخل النطاقات. المتغيرات المعلنة في النطاق الخارجي متوفرة في النطاق الداخلي.
يتكون النطاق المعجمي من نطاقات خارجية محددة بشكل ثابت. أي وظيفة ، بغض النظر عن مكان تنفيذها ، لديها إمكانية الوصول إلى المتغيرات من نطاقها المعجمي (هذا هو جوهر عمليات الإغلاق).
آمل أن تكون المقالة مفيدة لك. شكرآ لك على أهتمامك.