يمكن فهم النطاق المزعوم ببساطة على أنه نطاق (منطقة) يمكن قراءتها وكتابتها. قد يقول بعض الطلاب الذين لديهم خبرة في JS: "JS ليس لديه نطاق على مستوى الكتلة". بالإضافة إلى النطاق العالمي ، يمكن للوظائف فقط إنشاء نطاقات. ميزة واحدة من النطاق هي أنه يمكن عزل المتغيرات.
نستخدم بعض الأمثلة لمساعدتنا على فهم النطاق في JS.
تنبيه (أ) ؛ var a = 1 ؛
إذا كان الطلاب الذين لا يعرفون النطاق على الإطلاق يقولون إن التنبيه هو 1 أو الإبلاغ عن خطأ ؛ لكنها في الواقع غير محددة.
عند الحديث عن هذا ، دعنا نتحدث أولاً عن بعض الاستعدادات التي تم إجراؤها قبل تحليل خط الكود سطرًا.
قبل قراءة سطر الكود ، ستقوم JS ببعض أعمال "ما قبل الإسلام" وستجد بعض "الأشياء الصغيرة" مقدمًا. بالطبع ، لن تجد "JS Parser" بعض البيانات عرضية ، وسوف يجدها وفقًا لـ VAR و Function و Parameters.
"JS Parser" هو "كسول" نسبيا. قبل تشغيل الكود رسميًا ، سيقوم بتعيين المتغير الذي أعلنه VAR إلى غير محدد ، أي var a = غير محدد ؛ سوف يعتبر الوظيفة بأكملها كتلة رمز ، بغض النظر عن مقدار الكود الموجود. سيتم قول المعلمات في الأمثلة لاحقًا.
بعد الانتهاء من جميع الاستعدادات ، يبدأ "JS Parser" في تنفيذ سطر الكود. الآن ، دعونا نحلل المثال الذي بدأناه ومن السهل فهم سبب عدم تعريفه.
لنلقي نظرة على المثال التالي
تنبيه (أ) ؛ var a = 1 ؛ تنبيه (أ) ؛ var a = 2 ؛ تنبيه (أ) ؛
دعونا نحلل هذا قليلاً
أولاً "التحضير": سيبحث المحلل
عند قراءة السطر الثاني A = غير محدد ؛
عند قراءة السطر الرابع ، لا يزال A = غير محدد ؛
تنفيذ الرمز الرسمي لكل خط على حدة:
تنبيه الخط الأول: غير محدد
السطر الثاني A = 1 ؛
الخط 3 تنبيه: 1 ؛
تنبيه العنصر الخامس: 2
دعونا نلقي نظرة على المثال أدناه
تنبيه (أ) ؛ var a = 1 ؛ تنبيه (أ) ؛ الدالة A () {Alert (2) ؛ } تنبيه (أ) ؛ var a = 3 ؛ تنبيه (أ) ؛ الدالة A () {Alert (4) ؛ } تنبيه (أ) ؛دعونا نحلل هذا قليلاً شيئًا فشيئًا
أولاً ، "Pre-Parse": سيبحث المحللون عن وظيفة var ؛
عند قراءة السطر الثاني A = غير محدد ؛
عند قراءة السطر الرابع A = الدالة A () {Alert (2) ؛} // جميع الوظائف هي كتلة الوظيفة بالكامل قبل تشغيل الكود رسميًا ؛ عندما يواجه متغير اسمًا مكررًا ، يتم ترك متغير واحد فقط. إذا كانت المتغير والوظيفة مكررة ، فسيتم ترك الوظيفة فقط.
عند قراءة السطر السادس ، a = function a () {Alert (2) ؛}
عند قراءة السطر الثامن ، a = function a () {Alert (4) ؛}
تنفيذ الرمز الرسمي لكل خط على حدة:
تنبيه السطر الأول: الدالة A () {Alert (4) ؛}
السطر الثاني A = 1 ؛ // يمكن للتعبير تعديل القيمة المسبقة المسبقة!
الخط 3 تنبيه: 1 ؛
الخط الرابع من الوظيفة لا يسمى ، تخطي.
تنبيه العنصر الخامس: 1 ؛
السطر السادس A = 3 ؛
الخط 7 تنبيه: 3
وظيفة الخط الثامن لا تسمى ، تخطي.
الخط 9 تنبيه: 3
كما هو مبين في الشكل:
استمر في رؤية المثال:
var a = 1 ؛ function fn1 () {Alert (a) ؛ // غير محدد var a = 2 ؛} fn1 () ؛ تنبيه (أ) ؛ // 1أولاً "التحضير": سيبحث المحللون عن وظيفة var
عند قراءة السطر الأول A = غير محدد ؛
عند قراءة السطر الثاني fn1 = function fn1 () {Alert (2) ؛ var a = 2 ؛}
التنفيذ الرسمي لكل خط تلو الآخر من الكود: السطر الأول A = 1 ؛
استدعاء وظيفة السطر السادس ، أدخل نطاق الوظيفة وما زال يتمتع مسبقًا في نطاق الوظيفة ، ثم قم بتنفيذه سطرًا.
التحضير داخل الوظيفة: أ = غير محددة ؛
التنفيذ: تنبيه: غير محدد ؛
أ = 2 ؛ // A في هذا الوقت هو فقط في نطاق الوظيفة ولن يؤثر على العالم في العالم
يتم تنفيذ الوظيفة وتعود إلى النطاق العالمي ؛
الخط السابع في حالة تأهب: 1 ؛
يكمل:
var a = 1 ؛ function fn1 () {Alert (a) ؛ // 1 a = 2 ؛} fn1 () ؛ تنبيه (أ) ؛ // 2الفرق الوحيد بين المثال أعلاه هو أن A في الوظيفة لا يحتوي على VAR ، ويحلل النقاط الرئيسية فقط.
في تنبيه السطر الثالث (A) ، في نطاق الوظيفة ، نظرًا لعدم وجود VAR A في الوظيفة ، فإن "المحلل" يبحث عن A إلى النطاق العلوي لنطاق الوظيفة (تحديد العلاقة بين المستوى العلوي والثانوي يعتمد على النطاق الذي تم إنشاؤه ، وتحت النطاق الذي تم إنشاؤه ، وهو النطاق الذي يتمثل فيه النطاق). في هذا الوقت ، فإن المستوى العلوي من الوظيفة هو النطاق العالمي. في النطاق العالمي ، A = 1 ، لذلك في هذا الوقت ، تنبيه السطر الثالث: 1 ، ثم السطر الرابع ، A = 2 يعين القيمة ، لا يزال هناك A في نطاق الوظيفة ، لذلك ابحث عن A في نطاق المستوى العلوي ، أي ، النطاق العالمي ، 2 ،
يجب فهم هذه النقطة بوضوح وأن تنتبه إلى الفرق بين VAR أو لا.
التالي:
var a = 1 ؛ وظيفة fn1 (a) {Alert (a) ؛ // غير محدد A = 2 ؛ } fn1 () ؛ تنبيه (أ) ؛ // 1الفرق بين هذا المثال والما السابق هو أن هناك معلمة إضافية. وظيفة المعلمة تعادل متغيرًا محليًا ، أي أنه سيكون هناك var a = غير محدد في الإرشاد المسبق في الوظيفة. لذلك ، فإن تنبيه السطر الثالث: غير محدد ، والسطر الرابع A = 2 يغير A في نطاق الوظيفة ، والذي لا يؤثر على السياق العالمي. تنبيه الخط السابع: 1 ؛
ثم:
var a = 1 ؛ function fn1 (a) {Alert (a) ؛ // 1a = 2 ؛} fn1 (a) ؛ Alert (a) ؛ // 1هذا المثال يختلف إلى حد ما عن المركز السابق. عندما يتم استدعاء الوظيفة في السطر السادس ، يتم تمرير المعلمة. المعلمة الفعلية A من وظيفة السطر السادس هي 1 من المتغير العالمي A = 1. عند تنفيذ الوظيفة ، والسطر الثاني A = 1 ، وبالتالي تنبيه السطر الثالث: 1 ، وتنبيه الخط السابع: 1.
انتبه إلى الفرق بين هذه الأمثلة ولا تخلط بينها.
واحد آخر:
var a = 1 ؛ function en () {var a = 2 ؛ fn () ؛} function fn () {Alert (a) ؛ // 1} en () ؛لم يتم الإعلان عن A في FN ، وتحتاج إلى أخذ القيمة في النطاق الذي يتم فيه إنشاء الوظيفة - وهي "تم إنشاؤها" ، وليس "استدعاء" نطاق الوظيفة.
ملاحظة: مفاهيم النطاق والسياق في JavaScript
تعد النطاقات والسياقات في JavaScript فريدة من نوعها في هذه اللغة ، ويرجع ذلك جزئيًا إلى المرونة التي يجلبونها. كل وظيفة لها سياق ونطاق متغير مختلف. يتم دعم هذه المفاهيم ببعض أنماط التصميم القوية في JavaScript. ومع ذلك ، فإن هذا يجلب أيضًا تشويشًا كبيرًا للمطورين. يكشف ما يلي بالكامل الاختلافات في السياق والنطاق في JavaScript وكيف تستخدمها أنماط التصميم المختلفة.
السياق مقابل النطاق
السؤال الأول الذي يتم توضيحه هو أن السياق والنطاق مفاهيم مختلفة. على مر السنين ، لاحظت أن العديد من المطورين غالباً ما يخلطون بين هذين المصطلحين ، ويصفون خطأً بأنه الآخر. لكي نكون منصفين ، أصبحت هذه الشروط مربكة للغاية.
كل مكالمة دالة لها نطاق وسياق مرتبط به. في الأساس ، يعتمد النطاق على الوظيفة والسياق يعتمد على الكائن. بمعنى آخر ، يرتبط النطاق بالوصول إلى المتغيرات في كل مرة يتم فيها استدعاء الوظيفة ، وكل مكالمة مستقلة. السياق هو دائمًا قيمة الكلمة الرئيسية ، مرجعًا إلى الكائن الذي يستدعي الرمز القابل للتنفيذ الحالي.
ما سبق هو نطاق JavaScript الذي قدمه لك المحرر (موصى به). آمل أن يكون ذلك مفيدًا لك. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر إليك في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!