Conceptos: El patrón de diseño del módulo JavaScript
Los conflictos de ámbito
En JavaScript, cuando se define una variable usando el var
elemento, se encuentra dentro de la función que se define. Si define una variable sin usar var
, se le asigna el ámbito global. Esto significa que las variables globales son vulnerables a colisiones con otros scripts de su página.
Veamos un ejemplo de código. En el siguiente código, la función y las variables existen dentro del ámbito de la página.
// script 1
var incrementCount = function() {
count++;
}
var myButton = document.getElementById('buttonId');
var count = 0;
myButton.onclick = incrementCount;
Ahora, digamos que hay una función fuera de su script que también modifica la count
variable global. Esta colisión de scripts puede provocar resultados inesperados.
// script 2
var countVideos = function(videoList) {
count = videoList.length;
}
Resultados:
- El usuario selecciona el
myButton
botón dos veces, incrementando lacount
variable enscript 1
.count
= 2
- La
countvideos
función se llama que existe enScript 2
, pero también en su página web. Digamos que elvideoList
contiene 10 elementos. Ahora, la variablecount
global tiene un valor de 10.count
= 10
- La próxima vez que el usuario seleccione el
myButton
botón, lacount
variable devolverá resultados inesperados.- Esperado:
count
= 3 - Efectivo:
count
= 11
- Esperado:
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 nombres de funciones y 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. El código dentro de un cierre no es accesible por otros scripts. Por lo tanto, esto le da 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 haber sido analizada, en lugar de esperar a que otro código llame a la función.
(function () {
// your code
}());
Los cierres pueden ser potentes, ya que proporcionan 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 ámbito de cierre. Pero, su código dentro del cierre todavía puede acceder a cualquier variable global o función.
Globales
Aunque JavaScript tiene una característica conocida como globales implícitos, 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 buscando una var
declaración que coincida con el nombre. Si no se encuentra ninguno, se supone que la variable es global.
Pasar en globals
Con la función anónima, puede pasar explícitamente parámetros globales. Esto se denomina importación de parámetros en su código.
Un ejemplo:
- Línea 1: define el nombre de los parámetros que se pasan a la función. Observe que no tienen que coincidir con los nombres de la línea 3. Aquí, el
window
objeto se pasa a un parámetro llamadowindow1
. - Línea 3: pasa el
window
objeto a la función.
(function( 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 ser útil si desea una manera fácil de verificar si otras variables están definidas.
if(variable1 === undefined)
Exportar globales
También es posible que desee pasar variables y funciones fuera de su función anónima. Puede hacer esto usando el return
valor.
Un ejemplo:
- Línea 1: asigna nuestra función anónima a
BCLS
. Este valor puede ser cualquier cosa que usted elija. En este ejemplo, estamos utilizando BCLS (Brightcove Learning Services).
var BCLS = (function( window1, undefined ) {
var object1 = {};
object1.count = 1;
object1.method = function () {
...
}
return object1;
})(window);
El object1
objeto ahora está disponible globalmente con dos propiedades públicas, una variable llamada count
y una función denominada method
. Se puede acceder a ellos fuera de nuestra función anónima como:
BCLS.object1.count
BCLS.object1.method
Ejemplos completos
Aquí hay algunos ejemplos completos del patrón de diseño del módulo JavaScript.
Ejemplo 1
En este ejemplo se muestra cómo crear variables y funciones privadas y públicas mediante el patrón de módulo.
- Variables privadas:
myvar
,myvar2
- Funciones privadas:
fname
,fname2
- Variable pública:
myvar3
- Función pública:
fname3
var BCLS = ( function() {
var myvar = value,
myvar2 = value;
fname = function() {
...
};
fname2 = function() {
...
};
return {
fname3 : function() {
...
},
myvar3 = value;
};
}());
Ejemplo 2
Este ejemplo pasa objetos globales y expone una función pública.
var BCLS = (function( window, document, videojs ) {
var myvar = value;
// use a global object passed into the anonymous function
videojs.registerPlugin('overlay');
fname = function() {
...
}
return {
fname2 : function() {
...
}
}
})(window, document, videojs);
// call the public function fname2
var newvar = BCLS.fname2();
Ejemplos de código
Algunos de nuestros ejemplos de código utilizan JavaScript Module Design Pattern, y puede revisarlos para obtener ideas sobre cómo implementar este patrón.