Analisando o Padrão "Módulo" em JavaScript

Muitas linguagens de programação possuem mecanismos para ocultar, por exemplo, métodos e propriedades de classes. O JavaScript não possui ferramentas internas que permitem, sem esforço extra, obter esses efeitos. No entanto, essas coisas podem ser imitadas usando outros recursos de idioma.

imagem

O material, cuja tradução publicamos hoje, é dedicado à análise do padrão de design “Módulo”, que permite ocultar informações privadas em falhas, dando acesso apenas ao que o desenvolvedor decidiu tornar público. Este artigo é voltado principalmente para programadores iniciantes - para aqueles que parecem familiarizados com coisas como fechamentos e IIFE, mas ainda não os usaram com muita confiança.

IIFE


Você pode controlar o escopo das variáveis ​​em JavaScript usando o padrão "Módulo". Para criar um escopo privado, você pode usar o fechamento. Como você sabe, as funções criam seu próprio escopo, cujo conteúdo é separado do escopo global:

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

Diante de nós está a chamada função de auto-invocação ( IIFE , Expressão de Função Imediatamente Invocada, imediatamente denominada expressão funcional). Essa função é executada imediatamente após sua declaração. É conveniente usar essas funções para resolver um determinado problema que precisa ser resolvido apenas uma vez, sem deixar nada supérfluo no escopo global. Dentro desta função (assim como dentro de outras funções) é criado um escopo privado, inacessível do lado de fora. Ou seja, se outra função for declarada dentro desse escopo, depois que o IIFE for executado, o acesso a ele não será possível.

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

Agora vamos tentar acessar a função myFunction partir do texto principal do programa:

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

Como você pode ver, como esperado, esta chamada leva a um erro. Isso nos diz que essa função não está disponível no escopo do qual estamos tentando acessá-la. De fato, nada de útil é feito nos dois exemplos acima. Precisamos desses exemplos apenas para nos preparar para a análise do padrão "Módulo".

Retornando um objeto do módulo IIFE e API


Como garantir que uma função declarada dentro de outra função ainda possa ser acessada? De fato, o que vamos falar agora é o padrão "Módulo". Considere o seguinte exemplo.

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

Você pode perceber que o mesmo IIFE é usado aqui como antes, mas agora um objeto com um método é retornado da função, que pode ser acessada no escopo global. Naturalmente, esse método não pode ser chamado. Deve-se notar que, neste exemplo, não usamos os recursos de fechamento, falaremos sobre isso abaixo.

Um objeto retornado do IIFE é um objeto comum que pode ter muitos métodos e propriedades. Eles formam uma interface pública ou API de módulo.

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

Variáveis ​​e funções privadas armazenadas no fechamento


Agora é hora de falar sobre variáveis ​​e funções privadas. Por exemplo, podem ser algumas funções auxiliares que garantem a operação dos mecanismos internos do módulo.

Podem ser variáveis ​​temporárias ou variáveis ​​que desempenham o papel de armazenamento de determinados dados, acesso ao qual queremos controlar rigidamente. Estamos interessados ​​nesse módulo de dispositivo, quando apenas o que deve estar disponível para o mundo exterior e tudo o mais está oculto. De fato, tudo o que, em nosso exemplo, será declarado fora do objeto retornado do IIFE, se tornará privado.

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

O método publicMethod deste exemplo pode ser chamado de fora, mas a função privateMethod não privateMethod , porque está em um escopo privado, em um fechamento. São precisamente essas funções, inacessíveis do lado de fora, que podem desempenhar o papel de mecanismos auxiliares dos módulos. Eles podem ser usados ​​para gerenciar estruturas de dados internas, fazer algumas chamadas para determinados serviços e em outras situações.

Ao trabalhar com essas funções, é necessário considerar que elas podem ser acessadas de outras funções declaradas no mesmo escopo, incluindo os métodos do objeto retornado do IIFE e mesmo depois que o comando return retornar esse objeto . Ou seja, métodos públicos têm acesso a funções privadas, eles podem interagir com eles, mas no escopo global, essas funções privadas não estão disponíveis.

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

Graças a isso, podemos proteger o código contra interferências não autorizadas e proteger o escopo global da poluição. Se isso não for feito, então, por um lado, a operação dos mecanismos internos dos módulos pode ser interrompida acidental ou deliberadamente, devido ao fato de que o código externo se refere a funções ou variáveis ​​que ele não deve acessar. Por outro lado, se você não usar a abordagem descrita aqui, muitas coisas desnecessárias caem no escopo global, o que, por exemplo, pode levar a conflitos de nomes.

Aqui está um exemplo de um objeto retornado do IIFE que contém métodos públicos e pode acessar funções privadas:

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

Nomeando recursos públicos e privados


Há um acordo, segundo o qual, no início dos nomes de funções privadas, coloca um sublinhado. Isso permite, apenas olhando o código, entender quais funções são internas e quais estão disponíveis publicamente. Por exemplo, pode ser assim:

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

Sumário


Neste artigo, examinamos um padrão simples de "Módulo", que, através do uso de um fechamento formado por uma expressão funcional imediatamente chamada e retornada de uma expressão de objeto, permite criar métodos públicos e funções privadas e estruturas de dados que não podem ser operadas diretamente de fora. Este modelo permite ocultar os detalhes de implementação dos módulos, protegendo-os de alterações acidentais ou intencionais, e ajuda a manter limpo o escopo global.

Caros leitores! Você usa o padrão "Módulo" em seus projetos JS?

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


All Articles