Conceptos: El patrón de diseño del módulo JavaScript

En este tema, aprenderá a utilizar el patrón de diseño de módulos de JavaScript para reducir la posibilidad de que su código entre en conflicto con otros scripts de su página web.

Uso de variables de JavaScript

Antes del lanzamiento de ES2015 (ES6), las variables de JavaScript solían declararse mediante el var palabra clave. Pero, con la introducción de ES6, let y const se agregaron como una nueva forma de declarar variables. Esto genera con frecuencia preguntas sobre qué palabra clave debe usarse y cuándo.

Aquí hay una breve explicación de las diferentes formas de declarar una variable en JavaScript.

Usando var

Usando var es el método más antiguo de declaración de variables en JavaScript. Cuando se define dentro de una función, cualquier var está restringida a esa función, pero una var es global cuando se define fuera de una función.

// Global Declaration
var variable = value;

const varExampleFunction = () => {
    // Local Declaration
    var variable = value;
}

usando let

El let se introdujo con ES6, este tipo de declaración tiene alcance de bloque, lo que significa que las variables declaradas con let sólo se puede acceder en el bloque o función en el que está definido.

const letExampleFunction = () => {
    let variable = value;
}

usando const

Como let , const también se introdujo con ES6. Es por esto que ambas declaraciones son muy similares. La principal diferencia es que const apunta a datos en la memoria que contienen valores constantes, y const las variables de referencia no se pueden reasignar a un objeto diferente en la memoria.

 const constExampleFunction = () => {
    const variable = value;
}

Conflictos de alcance

En JavaScript, cuando define una variable usando el var , let o const elemento, está dentro del ámbito de la función que se define. Las variables globales son vulnerables a colisiones con otros scripts en su página.

Veamos un ejemplo de código. En el siguiente código, la función y las variables existen dentro del alcance de la página.

// script 1
const incrementCount = () => {
    count++;
}

const myButton = document.getElementById('buttonId');
let count = 0;

myButton.onclick = incrementCount;

Ahora, digamos que hay una función fuera de su script que también modifica el global count variable. Esta colisión de scripts puede provocar resultados inesperados.

// script 2
const countVideos = videoList => {
    count = videoList.length;
}

Resultados:

  1. El usuario selecciona el myButton dos veces, incrementando el count variable en script 1.
    • count = 2
  2. Se llama a la countvideos función que existe en la página web Script 2, pero también en su página web. Digamos que el videoList contiene 10 elementos. Ahora el count La variable global tiene un valor de 10.
    • count = 10
  3. La próxima vez que el usuario seleccione myButton botón, el count La variable devolverá resultados inesperados.
    • Esperado: count = 3
    • Real: count = 11

Puede intentar evitar conflictos en sus scripts, pero no hay garantía de que los scripts de terceros incluidos en su página no utilicen funciones y nombres de variables similares.

Funciones anónimas

Una solución es envolver su código en una función anónima (también llamada cierre), que se ejecuta inmediatamente. Su código dentro de un cierre no es accesible por otros scripts. Entonces, esto le brinda una forma de crear funciones y variables privadas.

Aquí está la sintaxis de una función anónima:

  • Línea 3: incluye un conjunto adicional de paréntesis, que le dice a JavaScript que ejecute la función inmediatamente después de que se haya analizado, en lugar de esperar a que otro código llame a la función.
( () => {
    // your code
}());

Otro ejemplo de sintaxis:

var res = function( [arguments] ) { ... }

Los cierres pueden ser poderosos, ya que brindan privacidad y estado durante toda la vida útil de la aplicación. Para el código dentro del cierre, todas las variables y funciones están solo en el alcance del cierre. Pero su código dentro del cierre aún puede acceder a cualquier variable o función global.

Globales

Aunque JavaScript tiene una característica conocida como globales implícitas, puede hacer que su código sea difícil de administrar, ya que no es fácil determinar qué variables son globales. Para determinar si una variable es global, el intérprete tiene que caminar hacia atrás a través de la cadena de alcance en busca de una var declaración que coincide con el nombre. Si no se encuentra ninguno, se supone que la variable es global.

Pasar en globales

Con la función anónima, puede pasar explícitamente parámetros globales. A esto se le llama importar parámetros en su código.

He aquí un ejemplo:

  • Línea 1: define el nombre de los parámetros que se pasan a la función. Tenga en cuenta que no es necesario que coincidan con los nombres de la línea 3. Aquí el window el objeto se pasa a un parámetro llamado window1.
  • Línea 3: pasa el window objeto en la función.
( ( window1, undefined ) => {
    ...
})(window);

Dado que solo se pasa 1 objeto, pero hay dos parámetros, el valor de undefined será indefinido.

typeof undefined == "undefined"

Esto puede resultar útil si desea una forma sencilla de comprobar si se han definido otras variables.

if(variable1 === undefined)

Exportar globales

Es posible que también desee pasar variables y funciones fuera de su función anónima. Puede hacer esto usando el return valor.

He aquí un ejemplo:

  • Línea 1: asigna nuestra función anónima a BCLS. Este valor puede ser cualquier cosa que elija. En este ejemplo, usamos BCLS (Brightcove Learning Services).
const BCLS = ( ( window1, undefined ) => {
    var object1 = {};
    object1.count = 1;
    object1.method = function () {
        ...
    }
    return object1;
})(window);

La object1 El objeto ahora está disponible globalmente con dos propiedades públicas, una variable llamada count y una función llamada method. Se puede acceder a ellos fuera de nuestra función anónima como:

  • BCLS.object1.count
  • BCLS.object1.method

Ejemplos completos

A continuación, se muestran algunos ejemplos completos del patrón de diseño de módulos de JavaScript.

Ejemplo 1

Este ejemplo muestra cómo crear variables y funciones públicas y privadas utilizando el patrón de módulo.

  • Variables privadas: myvar, myvar2
  • Funciones privadas: fname, fname2
  • Variable pública: myvar3
  • Función pública: fname3
const BCLS = ( () => {
   var myvar = value,
       myvar2 = value;

   fname = () =>  {
        ...
   };
   fname2 = () =>  {
        ...
   };

   return {
        fname3 : () =>  {
             ...
        },
        myvar3 = value;
   };
}());

Ejemplo 2

Este ejemplo pasa objetos globales y expone una función pública.

const BCLS = ( ( window, document, videojs ) => {
  var myvar = value;

  // use a global object passed into the anonymous function
  videojs.registerPlugin('overlay');

  fname = () => {
      ...
  }
  return {
    fname2 : () => {
          ...
      }
  }
})(window, document, videojs);

// call the public function fname2
var newvar = BCLS.fname2();

Muestras de código

Algunos de nuestros ejemplos de código utilizan el patrón de diseño de módulos de JavaScript, y puede revisarlos para obtener ideas sobre cómo implementar este patrón.