¡Hola! Me parece que andas usando un bloqueador de anuncios =( ¿Nos desbloqueas? ¿Por qué?
F13

Funcion 13

Función anónima auto-invocada en JavaScript

Hace pocos días, recibí un interesante comentario en el artículo de “Cargando contenido AJAX con jQuery usando imagen de cargando“. En él, Eduardo me preguntaba básicamente, qué tipo de estructura es esta:

(function($){ 
//Código aquí 
})(jQuery);

Cuando comencé a usar JavaScript con jQuery de forma extensiva en mi día a día, una de las cosas que me preocupaba al principio, era cómo organizar mi código. Al principio, mi código era parecido a esto:

var primera = 'Hola';  
var segunda = 'Don Pepito';

function saludo() {  
  return [primera + segunda].join(' ');
}
alert(saludo());  

Este estilo de código es normal, funciona bien y, en principio no causa problemas.

Cuando trabajas en una aplicación grande, este tipo de código se convierte en algo salvaje. Todas las funciones y variables están en el ámbito global por lo que puede que si incluyes dos archivos en tu página, estos colisionen entre sí porque uses funciones con el mismo nombre o variables, etc.

Así que empiezas a aprender el arte de las funciones anónimas autoinvocadas. Veámosla de nuevo:

(function() {
  alert('Hola Don Pepito');
})();

Ahora vamos a despedazarla en trocitos már cortos. Este código tiene tres partes.

Primero, la función anónima:

(function(){ 
  // Código 
})();

Segundo, el código de la función. En este caso solo un alert.

alert('Hola Don Pepito');  

Y por último, y realmente más importante, lo que añadimos al final del todo:

();

Esos dos paréntesis hacen que lo que está antes de los paréntesis, sea ejecutado de forma inmediata. ¿Recordáis el alcance/scope en JavaScript? JavaScript tiene un alcance a nivel de función. Todas las variables definidas dentro de esa función anónima no están disponibles al resto del mundo, usando una closure que la deja oculta al resto.

Veamos curiosidades de nuestro ejemplo anterior:

(function() {
  var primera = 'Hola',
    segunda = 'Don Pepito';

  function saludo() {
    return [primera + segunda].join(' ');
  }
})(); 
// Nada de esto funciona! 
alert(saludo());  
alert(primera);  
alert(segunda);  

Las tres últimas líneas nos soltarán una excepción porque no son accesibles fuera de la función anónima. Tenemos que hacer que sean visibles:

(function() {
    var primera = 'Hola',
      segunda = 'Don Pepito';

    function saludo() {
      return [primera + segunda].join(' ');
    }
    window.primera = saludo; // Lo hacemos global 
})(); 
alert(saludo()); // Esto funciona!  
// Esto sigue sin funcionar 
alert(primera);  
alert(segunda);  

Una de las ventajas que tenemos de hacer esto, es que puedes limitar el acceso a variables y funciones haciéndolas privadas en la práctica y dejando expuestos tan solo una serie de funciones de tu elección.

Lo que yo hago habitualmente ahora en mis ejemplos, es pasar un objeto común como jQuery o window. Por ejemplo, cuando se escribe un plugin de jQuery es buena idea empezar con algo así:

(function(window, document, $, undefined) { 
  // Código del plugin 
})(window, document, jQuery);

A la hora de comprimir nuestro código, esta forma de escribirlo suele provocar que las variables que reciben por parámetros sean renombradas. Por ejemplo:

(function(a, b, $, c){ 
  // Código del plugin 
  console.log(c === undefined); // True 
})(window, document, jQuery);

Además, si te has fijado, pasamos jQuery como $ lo cual nos permite usar otros frameworks sin tener que usar jQuery en modo noConflict.

Quizá valga la pena destacar que los nombres de las variables pueden ser los que te parezcan:

(function(me, gusta, mucho, programar){ 
  mucho('a').hide(); 
})(window, document, jQuery);

Y, aunque el código funcionaría, no es para nada recomendable el hacer algo así.

Espero haber resuelto algunas dudas y que el artículo haya sido de interés. Recuerda que si el artículo te pareció interesante, útil o incluso equivocado, por favor considera el dejar un comentario. ¡Lo apreciaré mucho!

Programador Front-end en First + Third y Potato. Trabajando con JavaScript y HTML5 desde el corazón de Sevilla.

Comentarios ¡Únete a la conversación!