Javascript Module Pattern: métodos y propiedades públicas o privadas
22 de Enero 2009
Una de las ventajas que se me escapaba en una entrada anterior sobre el uso de la programación orientada a objetos en javascript, frente a la programación orientada a funciones (sintaxis tradicional), era el de la ocultación de funciones y variables, que permite evitar posibles conflictos entre scripts, sobrescritura accidental, etc.
Cuando creamos una función en javascript al estilo tradicional, (function muestraAlert(){alert(’Hola mundo’)}), estamos añadiendo implícitamente un método al objeto global window. De hecho, podríamos llamar a nuestra función mediante window.miFuncion(), aunque nunca lo hagamos así. Las variables globales pueden ser accedidas desde cualquier parte del código o desde otro script, como comentaba en el párrafo anterior, con los riesgos que esto supone.
La POO minimiza este riesgo al englobar las variables y funciones dentro de un objeto, convirtiéndo las variables en propiedades y las funciones en métodos del objeto, de manera que sólo podamos acceder a ellas a través del objeto al que pertenecen.
Ejemplo:
MiCoche = {
// propiedades
color: 'rojo',
combustible: 'diesel',
// métodos
acelerar: function(){
// instrucciones...
}
}
Sólo puedo acceder desde fuera del objeto a la variable “color”, propiedad del objeto “MiCoche”, a través de MiCoche.color
De esta forma nuestros métodos y propiedades están “suficientemente” protegidos, pero todavía es posible acceder a ellos desde el exterior mediante Objeto.propiedad u Objeto.metodo()
Es posible que nos interese que determinadas propiedades o métodos no puedan ser accedidos desde el exterior nunca, de ninguna manera posible. Por ejemplo, podemos tener unas variables que sean usadas por un método privado y no tengan por qué ser visibles ni modificables desde el exterior en ningún momento. Esto podría ser comparable con lo que en los lenguajes que se consideran realmente orientados a objetos, se conoce como encapsulación:
hacer las variables que son innecesarias para el tratamiento del objeto pero necesarias para su funcionamiento privadas, asi como las funciones que no necesitan interacción del usuario o que solo pueden ser llamadas por otras funciones dentro del objeto
Esto se puede conseguir gracias a lo que en Javascript se llama Module Pattern, que consiste en la asignación de una función anónima a una variable y su autoejecución inmediata. Todas las variables y funciones que se encuentren dentro de esta función serán sólo accesibles desde la propia función, es decir, actuarán como métodos y propiedades privadas.
Ejemplo:
var MiCoche2 = function(){
var color = 'rojo';
var combustible = 'diesel';
}();
^^ Estos paréntesis provocan la ejecución inmediata de la función
La buena noticia es que devolviendo un objeto, conseguiremos también proporcionar métodos y propiedades públicas, accesibles mediante MiCoche2.metodo() o MiCoche2.propiedad
Ejemplo:
var MiCoche2 = function(){
// propiedades privadas
var acelerador = 'pedal derecho';
[...]
// métodos y propiedades públicas
return { // devolvemos un objeto
color: 'rojo',
acelerar: function(){
// instrucciones
},
frenar: function(){
}
}
}();
^^ provocamos la ejecución inmediata y la devolución de los métodos y propiedades contenidos dentro del objeto devuelto por return.
Como se puede ver en el ejemplo, dentro de return usamos la notación literal de objetos como en el primer ejemplo expuesto (MiCoche), ya que de un objeto se trata. Para quien no le guste o prefiera la sintaxis tradicional, siempre se puede recurrir al método que proponen en wait-till-i.com, que consiste en la creación de un objeto vacío dentro del objeto principal, al que se le van añadiendo métodos y propiedades y que finalmente se devuelve mediante return.
Ejemplo:
var MiCoche2 = function(){
// propiedades privadas
var acelerador = 'pedal derecho';
var obj = {}; // objeto vacío
obj.acelerar = function(){
// instrucciones
}
return pub;
}();
Sigo llamando a los métodos públicos mediante MiCoche2.acelerar(), etc.
¿Qué hay de la reutilización de código?
La técnica mola, pero tiene un pequeño problema: no podemos crear instancias del objeto MiCoche2 mediante new MiCoche2().
La solución es eliminar los paréntesis finales que causan la ejecución inmediata. Nuestro ejemplo final quedaría así:
var MiCoche3 = function(){
// propiedades y métodos privados
var propiedad = 'valor';
[...]
// propiedades y métodos públicos
return {
color: 'rojo',
metodo: function(){
},
[...]
}
}
// creamos una instancia de MiCoche3
var MiNuevoCoche = new MiCoche3();
// y redefinimos sus propiedades
MiNuevoCoche.color = 'negro';

Un comentario a “Javascript Module Pattern: métodos y propiedades públicas o privadas”
Comentario: #1
Mootools Dolar Safe Mode | Uninstallme, el Junio 28th, 2009:
[...] los plugins por document.id o bien encapsular el plugin en una función anónima. Como comentaba en Javascript Module Pattern, el uso de funciones anónimas nos permite tener variables privadas. De esta forma, podemos asignar [...]