تحليل نمط "الوحدة النمطية" في جافا سكريبت

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

الصورة

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

معهد التمويل الدولي


يمكنك التحكم في نطاق المتغيرات في JavaScript باستخدام نمط "الوحدة". من أجل إنشاء نطاق خاص ، يمكنك استخدام الإغلاق. كما تعلم ، تنشئ الدوال نطاقها الخاص ، الذي يتم فصل محتوياته عن النطاق العالمي:

(function () { //      })(); 

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

 (function () { var myFunction = function () {   //     }; })(); 

الآن دعنا نحاول الوصول إلى وظيفة myFunction من النص الرئيسي للبرنامج:

 myFunction(); // Uncaught ReferenceError: myFunction is not defined 

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

إرجاع كائن من وحدة IIFE و API


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

 //   var Module = (function () { return {   myMethod: function () {     console.log('myMethod has been called.');   } }; })(); //      Module.myMethod(); 

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

الكائن الذي تم إرجاعه من IIFE هو كائن عادي يمكن أن يكون له العديد من الأساليب والخصائص. وهي تشكل واجهة عامة أو واجهة برمجة تطبيقات للوحدة النمطية.

 //   var Module = (function () { return {   myMethod: function () {   },   someOtherMethod: function () {   } }; })(); //      Module.myMethod(); Module.someOtherMethod(); 

المتغيرات والوظائف الخاصة المخزنة في الإغلاق


حان الوقت الآن للحديث عن المتغيرات والوظائف الخاصة. على سبيل المثال ، يمكن أن تكون بعض الوظائف المساعدة التي تضمن تشغيل الآليات الداخلية للوحدة النمطية.

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

 var Module = (function () { var privateMethod = function () { }; return {   publicMethod: function () {   } }; })(); 

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

عند العمل مع هذه الوظائف ، عليك أن تضع في اعتبارك أنه يمكن الوصول إليها من الوظائف الأخرى المعلنة في نفس النطاق ، بما في ذلك طرق الكائن الذي تم إرجاعه من IIFE ، وحتى بعد أن يقوم أمر return بإرجاع هذا الكائن . أي أن الأساليب العامة لديها حق الوصول إلى الوظائف الخاصة ، ويمكنها التفاعل معها ، ولكن في النطاق العالمي ، لا تتوفر هذه الوظائف الخاصة.

 var Module = (function () { var privateMethod = function () { }; return {   publicMethod: function () {     //       privateMethod,      :     // privateMethod();   } }; })(); 

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

فيما يلي مثال لكائن تم إرجاعه من IIFE يحتوي على طرق عامة ويمكن الوصول إلى الوظائف الخاصة:

 var Module = (function () { var myModule = {}; var privateMethod = function () { }; myModule.publicMethod = function () { }; myModule.anotherPublicMethod = function () { }; return myModule; //      })(); //   Module.publicMethod(); 

تسمية الميزات الخاصة والعامة


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

 var Module = (function () { var _privateMethod = function () { }; var publicMethod = function () { }; return {   publicMethod: publicMethod, } })(); 

الملخص


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

أعزائي القراء! هل تستخدم نمط "الوحدة" في مشاريع JS الخاصة بك؟

Source: https://habr.com/ru/post/ar419997/


All Articles