أيضًا، تصوغ MDN تعريفها لـ \\\"النطاق العالمي\\\" على أنه \\\"النطاق الافتراضي لجميع التعليمات البرمجية التي تعمل في وضع البرنامج النصي.\\\" أعتقد أن المثال أعلاه هو ما يشيرون إليه.

أثناء استخدام الكائن العمومي window، يمكنك القيام بشيء مثل هذا:


window.username = \\\"غاريت\\\";
  window.username = \\\"Garrett\\\";
نطاق الوحدة

إذا كنت تعمل في مشروع Node.JS، فإن نطاق الوحدة هو ما ستعمل به على أعلى مستوى. كل ملف بامتداد .js (أو .ts) هو وحدة منفصلة، ​​مما يعني أنه سيتم الوصول إلى إعلاناتك على الأكثر من خلال كل شيء في ملف معين، ما لم تقم بتصديرها بشكل صريح.

على سبيل المثال، في user.ts، يمكن لكلتا الوظيفتين الوصول إلى اسم المتغير.


// user.tsاسم ثابت = \\\"غاريت\\\"؛وظيفة تحية () { console.log (\\\"مرحبا،\\\"، الاسم)}وظيفة تحية مرة أخرى () { console.log(\\\"مرحبًا مرة أخرى،\\\"، الاسم)}
  window.username = \\\"Garrett\\\";
ومع ذلك، في هذا الإصدار من user.ts، يمكن فقط لـ accessName() الوصول إلى اسم المتغير:


// user.tsوظيفة تحية () { اسم ثابت = \\\"غاريت\\\"؛ console.log (\\\"مرحبا،\\\"، الاسم)}وظيفة تحية مرة أخرى () { console.log(\\\"مرحبًا مرة أخرى،\\\"، الاسم)}
  window.username = \\\"Garrett\\\";
لاحظ أنه في كلتا الوحدتين، لا يتم تصدير أي شيء. بمعنى آخر، ليس لدى التعليمات البرمجية الموجودة في الوحدات الأخرى طريقة لمعرفة هذا الرمز، وبالتالي لا يمكن استيرادها واستخدامها. يمكننا تغيير ذلك بالرغم من ذلك:


// user.tsوظيفة التصدير تحية (الاسم: سلسلة) { console.log (\\\"مرحبا،\\\"، الاسم)}
  window.username = \\\"Garrett\\\";
الآن، تم تصدير كلتا الوظيفتين، وبالتالي يمكن استخدامهما بواسطة وحدات أخرى. يختلف هذا من الناحية الفنية عن مفهوم النطاق العالمي الذي تحدثنا عنه سابقًا، ولكنه مشابه من حيث أننا نجعل التعليمات البرمجية متاحة للتطبيق بأكمله عن طريق استيراده من وحدة إلى أخرى.

نطاق الوظيفة

لقد رأينا بالفعل نطاق الوظيفة. تحقق من الكود أدناه (إنه نفس الكود من أحد المقتطفات أعلاه):


// user.tsوظيفة تحية () { اسم ثابت = \\\"غاريت\\\"؛ console.log (\\\"مرحبا،\\\"، الاسم)}وظيفة تحية مرة أخرى () { console.log(\\\"مرحبًا مرة أخرى،\\\"، الاسم)}
  window.username = \\\"Garrett\\\";
حاول تشغيل هذا - سوف يحدث خطأ لـgreeAgain() لأن متغير الاسم الذي تحاول قراءته موجود فقط في سياق (أي \\\"النطاق\\\") لـgree().

ملاحظة: قد ترى أن هذا يُشار إليه باسم \\\"النطاق المحلي\\\".

نطاق الكتلة

يعد نطاق الكتلة أمرًا مثيرًا للاهتمام لأنه يعمل فقط مع أنواع المتغيرات الأحدث - على وجه التحديد، Let وconst، وليس var. دعونا نلقي نظرة.


{ دع الاسم الأول = \\\"غاريت\\\"؛ const lastName = \\\"Love\\\"; var fullName = \\\"غاريت لوف\\\"; // يمكن الوصول إلى الاسم الأول واسم العائلة هنا // يمكن الوصول إلى الاسم الكامل هنا}// لا يمكن الوصول إلى الاسم الأول واسم العائلة هنا// لا يزال من الممكن الوصول إلى الاسم الكامل هنا
  window.username = \\\"Garrett\\\";
في المثال أعلاه، يمكننا أن نرى أن 1) وضع التعليمات البرمجية داخل {} يؤدي إلى إنشاء كتلة تعليمات برمجية. 2) لا يمكن الوصول إلى المتغيرات المحددة باستخدام Let وconst إلا ضمن كتلة التعليمات البرمجية هذه. 3) المتغير الذي تم إنشاؤه باستخدام var لا يتبع قواعد نطاق الكتلة، حيث لا يزال من الممكن الوصول إليه خارج {}.

ملاحظة: تستخدم JavaScript الحديثة Let وconst لإعلانات المتغيرات وليس var.

يجب أن يتم الإدلاء بالتصريحات ضمن أصغر نطاق ضروري

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

","image":"http://www.luping.net/uploads/20240822/172432476966c71ba1f35b1.jpg","datePublished":"2024-08-22T19:06:09+08:00","dateModified":"2024-08-22T19:06:09+08:00","author":{"@type":"Person","name":"luping.net","url":"https://www.luping.net/articlelist/0_1.html"}}
"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > فهم النطاق في جافا سكريبت

فهم النطاق في جافا سكريبت

تم النشر بتاريخ 2024-08-22
تصفح:260

Understanding scope in JavaScript

تمت تغطية هذا الموضوع عدة مرات، ومع ذلك، أود أن أتحدث عن النطاق (باستخدام JavaScript) من منظور المشكلة التي يهدف إلى معالجتها.

ما هي المشكلة التي يحلها النطاق فعليًا؟

مع زيادة حجم التطبيقات، فإنها تزيد أيضًا من التعقيد - النطاق هو أداة لإدارة هذا التعقيد.

اقتران مقابل فصل

لنفترض أن لدينا نصف قطر متغير عالمي تم ضبطه على 7 والدالة createSpecialButton() التي ترجع زر "خاص":

let radius = 7;

function createSpecialButton(radius) {
  return 
}

const button = createSpecialButton(radius);

تقوم هذه الوظيفة بإرجاع زر بنصف قطر محدد، والذي تم ضبطه في هذه الحالة على 7. في الوقت الحالي، لا توجد مشكلة في الكود، لأننا نعرف ما تم تعيين نصف القطر عليه وبالتالي نعرف ما سيفعله الزر الناتج تبدو وكأنها. ومع ذلك، ماذا يحدث لما نضيفه إلى دالتين أخريين تعتمد كل منهما على متغير نصف القطر؟ يبدو الكود الخاص بنا الآن كما يلي:

let radius = 7;

function createSpecialButton() {
  return 
}

function profileButton() {
  radius = 10;
  return 
}

function registrationButton() {
  radius = 16;
  return 
}

const profileButton = profileButton();
const registrationButton = registrationButton();
const button = createSpecialButton();

بعد إجراء هذا التغيير، ما هي قيمة نصف القطر عند استدعاء createSpecialButton()؟ إذا خمنت 16، فأنت على حق.

بمجرد إضافة وظيفتين إضافيتين، قمنا بزيادة تعقيد التعليمات البرمجية الخاصة بنا بشكل كبير، ونحن نعيش الآن في عالم تعتمد فيه أجزاء متعددة وغير مرتبطة من التعليمات البرمجية على نفس التبعية. الآن، تخيل أن هذا كان تطبيقًا أكبر بكثير ومتكاملًا - وسرعان ما سيصبح من الصعب التفكير في مصدر أجزاء معينة من الحالة وكيفية إصلاح الأخطاء عند ظهورها.

لإصلاح ذلك، يمكننا تحديد متغيرات نصف قطر منفصلة لكل وظيفة:

function createSpecialButton() {
  const radius = 7;
  return 
}

function profileButton() {
  const radius = 10;
  return 
}

function registrationButton() {
  const radius = 16;
  return 
}

const profileButton = profileButton();
const registrationButton = registrationButton();
const button = createSpecialButton();

قد تنظر إلى هذا التغيير وتقول "حسنًا، حسنًا، ولكن يوجد الآن المزيد من التعليمات البرمجية - وهذا لا يبدو صحيحًا". هذا صحيح، هناك المزيد من التعليمات البرمجية، ولكن القليل من التعليمات البرمجية ليس أفضل إذا أدى إلى تعليمات برمجية أقل قابلية للصيانة - التغيير الذي أجريناه يحسن قابلية صيانة التعليمات البرمجية لدينا، وهذا أمر جيد دائمًا.

أنواع النطاق في جافا سكريبت

النطاق العالمي

يمكن الوصول إلى النطاق العالمي من خلال كل شيء عبر التطبيق بأكمله. إذا كنت تكتب تطبيق Node.JS، فمن المحتمل أنك لن تعمل مع النطاق العالمي أو تواجهه. ومع ذلك، إذا كنت تعمل في تطبيق ويب، فيمكنك وضع الإعلانات في نطاق عالمي باستخدام علامة البرنامج النصي أو استخدام window.SOMETHING.

على سبيل المثال، باستخدام علامة البرنامج النصي، يمكنك القيام بشيء مثل هذا:


أيضًا، تصوغ MDN تعريفها لـ "النطاق العالمي" على أنه "النطاق الافتراضي لجميع التعليمات البرمجية التي تعمل في وضع البرنامج النصي." أعتقد أن المثال أعلاه هو ما يشيرون إليه.

أثناء استخدام الكائن العمومي window، يمكنك القيام بشيء مثل هذا:


window.username = "غاريت";
  window.username = "Garrett";
نطاق الوحدة

إذا كنت تعمل في مشروع Node.JS، فإن نطاق الوحدة هو ما ستعمل به على أعلى مستوى. كل ملف بامتداد .js (أو .ts) هو وحدة منفصلة، ​​مما يعني أنه سيتم الوصول إلى إعلاناتك على الأكثر من خلال كل شيء في ملف معين، ما لم تقم بتصديرها بشكل صريح.

على سبيل المثال، في user.ts، يمكن لكلتا الوظيفتين الوصول إلى اسم المتغير.


// user.ts اسم ثابت = "غاريت"؛ وظيفة تحية () { console.log ("مرحبا،"، الاسم) } وظيفة تحية مرة أخرى () { console.log("مرحبًا مرة أخرى،"، الاسم) }
  window.username = "Garrett";
ومع ذلك، في هذا الإصدار من user.ts، يمكن فقط لـ accessName() الوصول إلى اسم المتغير:


// user.ts وظيفة تحية () { اسم ثابت = "غاريت"؛ console.log ("مرحبا،"، الاسم) } وظيفة تحية مرة أخرى () { console.log("مرحبًا مرة أخرى،"، الاسم) }
  window.username = "Garrett";
لاحظ أنه في كلتا الوحدتين، لا يتم تصدير أي شيء. بمعنى آخر، ليس لدى التعليمات البرمجية الموجودة في الوحدات الأخرى طريقة لمعرفة هذا الرمز، وبالتالي لا يمكن استيرادها واستخدامها. يمكننا تغيير ذلك بالرغم من ذلك:


// user.ts وظيفة التصدير تحية (الاسم: سلسلة) { console.log ("مرحبا،"، الاسم) }
  window.username = "Garrett";
الآن، تم تصدير كلتا الوظيفتين، وبالتالي يمكن استخدامهما بواسطة وحدات أخرى. يختلف هذا من الناحية الفنية عن مفهوم النطاق العالمي الذي تحدثنا عنه سابقًا، ولكنه مشابه من حيث أننا نجعل التعليمات البرمجية متاحة للتطبيق بأكمله عن طريق استيراده من وحدة إلى أخرى.

نطاق الوظيفة

لقد رأينا بالفعل نطاق الوظيفة. تحقق من الكود أدناه (إنه نفس الكود من أحد المقتطفات أعلاه):


// user.ts وظيفة تحية () { اسم ثابت = "غاريت"؛ console.log ("مرحبا،"، الاسم) } وظيفة تحية مرة أخرى () { console.log("مرحبًا مرة أخرى،"، الاسم) }
  window.username = "Garrett";
حاول تشغيل هذا - سوف يحدث خطأ لـgreeAgain() لأن متغير الاسم الذي تحاول قراءته موجود فقط في سياق (أي "النطاق") لـgree().

ملاحظة: قد ترى أن هذا يُشار إليه باسم "النطاق المحلي".

نطاق الكتلة

يعد نطاق الكتلة أمرًا مثيرًا للاهتمام لأنه يعمل فقط مع أنواع المتغيرات الأحدث - على وجه التحديد، Let وconst، وليس var. دعونا نلقي نظرة.


{ دع الاسم الأول = "غاريت"؛ const lastName = "Love"; var fullName = "غاريت لوف"; // يمكن الوصول إلى الاسم الأول واسم العائلة هنا // يمكن الوصول إلى الاسم الكامل هنا } // لا يمكن الوصول إلى الاسم الأول واسم العائلة هنا // لا يزال من الممكن الوصول إلى الاسم الكامل هنا
  window.username = "Garrett";
في المثال أعلاه، يمكننا أن نرى أن 1) وضع التعليمات البرمجية داخل {} يؤدي إلى إنشاء كتلة تعليمات برمجية. 2) لا يمكن الوصول إلى المتغيرات المحددة باستخدام Let وconst إلا ضمن كتلة التعليمات البرمجية هذه. 3) المتغير الذي تم إنشاؤه باستخدام var لا يتبع قواعد نطاق الكتلة، حيث لا يزال من الممكن الوصول إليه خارج {}.

ملاحظة: تستخدم JavaScript الحديثة Let وconst لإعلانات المتغيرات وليس var.

يجب أن يتم الإدلاء بالتصريحات ضمن أصغر نطاق ضروري

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

بيان الافراج تم نشر هذه المقالة على: https://dev.to/garrettlove8/understanding-scope-in-javascript-18fb?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3