Analyser le modèle "Module" en JavaScript

De nombreux langages de programmation ont des mécanismes pour masquer, par exemple, les méthodes et les propriétés des classes. JavaScript n'a pas d'outils intégrés qui permettent, sans effort supplémentaire, d'obtenir de tels effets. Cependant, de telles choses peuvent être imitées en utilisant d'autres fonctionnalités linguistiques.

image

Le matériel, dont nous publions la traduction aujourd'hui, est consacré à l'analyse du modèle de conception «Module», qui vous permet de masquer des informations privées dans des fermetures, donnant accès uniquement à ce que le développeur a décidé de rendre public. Cet article est principalement destiné aux programmeurs débutants - pour ceux qui semblent être familiers avec des choses comme les fermetures et l'IIFE, mais qui ne les ont pas encore utilisées avec beaucoup de confiance.

IIFE


Vous pouvez contrôler la portée des variables en JavaScript en utilisant le modèle «Module». Afin de créer une portée privée, vous pouvez utiliser la fermeture. Comme vous le savez, les fonctions créent leur propre portée, dont le contenu est séparé de la portée globale:

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

Devant nous se trouve la soi-disant fonction auto-invoquante ( IIFE , Immediately-Invoked Function Expression, immédiatement appelée expression fonctionnelle). Une telle fonction est exécutée immédiatement après sa déclaration. Il est pratique d'utiliser de telles fonctions afin de résoudre un certain problème qui ne doit être résolu qu'une seule fois, sans laisser quoi que ce soit de superflu dans la portée globale. A l'intérieur de cette fonction (ainsi qu'à l'intérieur d'autres fonctions) une portée privée est créée, inaccessible de l'extérieur. Autrement dit, si une autre fonction est déclarée à l'intérieur de cette portée, puis après l'exécution de IIFE, l'accès ne sera pas possible.

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

Essayons maintenant d'accéder à la fonction myFunction partir du texte principal du programme:

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

Comme vous pouvez le voir, comme prévu, cet appel conduit à une erreur. Cela nous indique que cette fonction n'est pas disponible dans la portée à partir de laquelle nous essayons d'y accéder. En fait, rien d'utile n'est fait dans les deux exemples ci-dessus. Nous n'avons besoin de ces exemples que pour préparer l'analyse du modèle de «module».

Retour d'un objet à partir du module IIFE et API


Comment s'assurer qu'une fonction déclarée dans une autre fonction est toujours accessible? En fait, ce dont nous allons parler maintenant, c'est du modèle «Module». Prenons l'exemple suivant.

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

Vous remarquerez peut-être que le même IIFE est utilisé ici qu'avant, mais maintenant un objet avec une méthode est renvoyé par la fonction, accessible à partir de la portée globale. Naturellement, cette méthode ne peut pas être appelée. Il convient de noter que dans cet exemple, nous n'utilisons pas les capacités de fermeture, nous en parlerons ci-dessous.

Un objet renvoyé par IIFE est un objet ordinaire qui peut avoir de nombreuses méthodes et propriétés. Ils forment une interface publique ou une API de module.

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

Variables et fonctions privées stockées dans la fermeture


Il est maintenant temps de parler des variables et fonctions privées. Par exemple, il peut s'agir de certaines fonctions auxiliaires qui assurent le fonctionnement des mécanismes internes du module.

Il peut s'agir de variables temporaires, ou de variables qui jouent le rôle de stockage de certaines données, dont nous voulons contrôler étroitement l'accès. Nous sommes intéressés par un tel module d'appareil, alors que ce qui devrait être disponible pour le monde extérieur, et tout le reste est caché. En effet, tout ce qui, dans notre exemple, sera déclaré en dehors de l'objet retourné par l'IFEF deviendra privé.

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

La méthode publicMethod de cet exemple peut être appelée de l'extérieur, mais la fonction privateMethod ne privateMethod pas, car elle est dans une étendue privée, dans une fermeture. Ce sont précisément ces fonctions, inaccessibles de l'extérieur, qui peuvent jouer le rôle de mécanismes auxiliaires des modules. Ils peuvent être utilisés pour gérer les structures de données internes, pour effectuer des appels vers certains services et dans d'autres situations.

Lorsque vous travaillez avec de telles fonctions, vous devez tenir compte du fait qu'elles sont accessibles à partir d'autres fonctions déclarées dans la même portée, y compris les méthodes de l'objet renvoyé par IIFE, et même après que la commande de return renvoyé cet objet . Autrement dit, les méthodes publiques ont accès à des fonctions privées, elles peuvent interagir avec elles, mais dans la portée globale, ces fonctions privées ne sont pas disponibles.

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

Grâce à cela, nous pouvons protéger le code contre les interférences non autorisées et protéger la portée mondiale de la pollution. Si cela n'est pas fait, alors, d'une part, le fonctionnement des mécanismes internes des modules peut être accidentellement ou délibérément perturbé, car le code externe fait référence à des fonctions ou des variables auxquelles il ne devrait pas accéder. D'un autre côté, si vous n'utilisez pas l'approche décrite ici, beaucoup de choses inutiles entrent dans la portée globale, ce qui, par exemple, peut entraîner des conflits de noms.

Voici un exemple d'un objet renvoyé par IIFE qui contient des méthodes publiques et peut accéder à des fonctions privées:

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

Nommer des fonctionnalités privées et publiques


Il y a un accord, selon lequel au début des noms des fonctions privées mettre un trait de soulignement. Cela permet, uniquement en regardant le code, de comprendre quelles fonctions sont internes et lesquelles sont accessibles au public. Par exemple, cela pourrait ressembler à ceci:

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

Résumé


Dans cet article, nous avons examiné un modèle de «module» simple qui, grâce à l'utilisation d'une fermeture formée par une expression fonctionnelle immédiatement appelée et renvoyée par une expression d'objet, vous permet de créer des méthodes publiques et des fonctions privées et des structures de données qui ne peuvent pas être directement exploitées de l'extérieur. Ce modèle vous permet de masquer les détails d'implémentation des modules, en les protégeant des modifications accidentelles ou intentionnelles, et aide à garder la portée globale propre.

Chers lecteurs! Utilisez-vous le modèle «Module» dans vos projets JS?

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


All Articles