Crear módulos en JavaScript






Fuente: https://www.wextensible.com/temas/javascript-closure/encapsulamiento.html#:~:text=El%20encapsulamiento%20usa%20las%20t%C3%A9cnicas,m%C3%A9todos)%20definidos%20en%20ese%20objeto.


Patrón módulo

<div class="ejemplo-linea">
    <div><input type="button" class="codigo"
        value="alert(modulo.variablePublica)"
        onclick="alert(modulo.variablePublica)" />
    </div>
    <div><input type="button" class="codigo"
        value="modulo.metodoPublico(Date())"
        onclick="modulo.metodoPublico(Date())" />
    </div>
</div>
<script>
    var modulo = (function(){
        //Variables y métodos privados
        var variablePrivada = "Esto es privado";
        var metodoPrivado = function(argumentoPrivado){
            alert(variablePrivada + " Fecha: " + argumentoPrivado);
        };
        //Devuelve un objeto con lo público
        return {
            variablePublica: "Esto es público",
            metodoPublico: function(argumentoPublico){
                variablePrivada += " (ahora es público a través del método público)";
                metodoPrivado(argumentoPublico);
            }
        };
    })();
</script>


Patrón singleton

<div class="ejemplo-linea">
    <div>La función pública no estará disponible hasta que instanciemos el singleton:</div>
        <input type="button" class="codigo"
        value="ejecutarFuncionPublica(unSingleton)"
        onclick="ejecutarFuncionPublica(unSingleton)" />
    <div>Si ahora instanciamos el singleton podemos pulsar el botón anterior y accedemos
    a la función pública</div>
        <input type="button" class="codigo"
        value="unSingleton = singleton.obtenerInstancia()"
        onclick="unSingleton = singleton.obtenerInstancia()" />
    <div>Cualquier otra instanciación conduce al mismo singleton</div>
        <input type="button" class="codigo"
        value="otroSingleton = singleton.obtenerInstancia()"
        onclick="otroSingleton = singleton.obtenerInstancia()" />
    <div>El cuerpo del módulo de todos los singletones es el mismo. La función pública
    accede a las mismas variables. Observe que la fecha-hora es la misma, momento
    en que se inició el primer singleton.</div>
        <input type="button" class="codigo"
        value="ejecutarFuncionPublica(otroSingleton)"
        onclick="ejecutarFuncionPublica(otroSingleton)" />
    <div>Podemos cerciorarnos de que es el mismo singleton</div>
        <input type="button" class="codigo"
        value="sonIguales(unSingleton, otroSingleton)"
        onclick="sonIguales(unSingleton, otroSingleton)" />
</div>
<script>
    var singleton = (function(){
        //Una instancia que haremos única
        var instancia;
        //iniciar el singleton: Esto devolverá el cuerpo del módulo,
        //lo privado en el closure y lo público en un objeto devuelto
        function iniciar(){
            var varPrivada = "Esto es privado. Fecha: " + Date();
            var funPrivada = function(){
                //hace algo
            };
            return {
                varPublica: "Esto es público",
                funPublica: function(){
                    alert(this.varPublica + " y " + varPrivada);
                }
            };
        }
        //En la autoejecución devolvemos una función que inicia
        //el singleton en todas las declaraciones
        return {
            obtenerInstancia: function(){
                if (!instancia){
                    instancia = iniciar();
                    alert("Singleton instanciado");
                } else {
                    alert("Este singleton ya fue instanciado");
                }
                return instancia;
            }
        };
    })();
    //Declaramos dos variables del singleton
    var unSingleton;
    var otroSingleton;
    //Funciones auxiliares para probar el ejemplo
    function ejecutarFuncionPublica(esteSingleton){
        //Si el singleton no ha sido instanciado no llamamos a la
        //función pública para evitar un error
        if (!esteSingleton){
            alert("El singleton no ha sido instanciado");
        } else {
            esteSingleton.funPublica();
        }
    }
    function sonIguales(uno, otro){
        //Sólo comparamos si hemos instanciado los dos singletones
        if (uno && otro){
            return alert(uno === otro);
        } else {
            alert("Instancie los dos singletones y luego compruebe esto");
        }
    }
</script>


Patrón lanzador o inicializador

<div class="ejemplo-linea">
    <div id="lanza-aqui"></div>
    <input type="button" class="codigo"
        value="unLanzador.verVariablePrivada()"
        onclick="unLanzador.verVariablePrivada()" />
    <input type="button" class="codigo"
        value="ejecutaOtroLanzador()"
        onclick="ejecutaOtroLanzador()" />
</div>
<script>
    var lanzador = (function(){
        //variables privadas
        var iniciado = false;
        var variablePrivada = "Esto es privado";
        var funcionPrivada = function(){
            alert(Date());
        };
        //En la auto-ejecución devuelve esta función lanzadora o iniciadora
        //del módulo, construyendo el HTML si no ha sido iniciado.
        return function(id, argumento){
            if (iniciado){
                alert("Lanzador ya fue iniciado. Sólo puede ejecutarse una vez.");
            } else {
                //Construye el HTML
                var donde = document.getElementById(id);
                var elemento = document.createElement("div");
                elemento.innerHTML = argumento;
                elemento.style.border = "blue solid 1px";
                elemento.onclick = funcionPrivada;
                donde.appendChild(elemento);
                iniciado = true;
                //Devuelve un objeto público
                return {
                    verVariablePrivada: function(){
                        alert(variablePrivada);
                    }
                };
            }
        };

    })();
    //
    var unLanzador = lanzador("lanza-aqui", "Contenedor generado por el lanzador. " +
                              "Haz click aquí para ver la fecha");
    var otroLanzador;
    function ejecutaOtroLanzador(){
        otroLanzador = lanzador("lanza-aqui", "Haz click aquí TAMBIÉN");
    }
</script>









Comentarios

Entradas populares