Funciones anónimas en nuestro código de jquer

Un patrón común en JavaScript son las funciones anónimas autoejecutables. Este patrón consiste en crear una expresión de función e inmediatamente ejecutarla. El mismo es muy útil para casos en que no se desea intervenir espacios de nombres globales, debido a que ninguna variable declarada dentro de la función es visible desde afuera.

Funciones nominales

Para ejecutar un bloque de instrucciones y realizar una tarea concreta, JavaScript utiliza las “funciones“, para agruparlas.
Para definir cada bloque (función), se le asigna un nombre. Cuando se quiera ejecutar ese bloque, se indica el nombre del bloque (función) correspondiente.

Sintaxis:

function nombre-de-la-función ()
{
//Grupo de instrucciones que realizará la función
}

Llamada a la función:

nombre-de-la-funcion ()
  • Si la función necesitara algún dato (parámetro), se lo tendríamos que entregar (pasar). Esta acción se realiza anotando entre los paréntesis”(” “)“los datos o variables que se aportan.
  • Al mismo tiempo, la función podría “devolvernos” un dato o una variable. Esto se consigue con la palabra clave “return“, que también podríamos emplear para salir de la función en un punto determinado de la misma.
  • El alcance de las variables; es decir, dónde pueden ser leídas o modificadas, depende de lo siguiente:
    • LOCAL. Cuando se define entre los límites “{” y “}” de la función por medio de la palabra clave “var“. Solo están accesibles dentro de ella, por tanto, incluso podrían tener el mismo nombre que otras fuera de ella, y no se interferirían.
    • GLOBAL. Cuando se define fuera. Se puede acceder a ella desde cualquier parte de la página Web. ¡¡Ojo con su empleo podrían existir interferencias!!Si asignamos un valor a una variable sin emplear la palabra clave “var“, se haga donde se haga, esa variable tendrá el alcance GLOBAL.
  • La vida de las variables; es decir su existencia, comienza donde se declaran o utilizan y finaliza: las locales al salir de la función, las globales al cerrar la página.
<!DOCTYPE html>
<html>
<head>
 <script>
//variable definida Global
 var superficie;
 //variable definida Global y asignado el valor 3
 var base=3;   /*
 Llama a la función areaTri
 Le pasa los parámetros: variable "base" y dato "5"  y recoge el resultado en la variable global "superficie"  */
 superficie= areaTri(base,5);
 //Muestra el resultado
 alert("La superficie es: " + superficie + " m2");
 //Define la función, que espera dos parámetros

 function areaTri(a,b){
 //Entrega el resultado del cálculo de la superficie
 return (a*b)/2;
 }
  </script>
</html>

Concluyamos con un ejemplo. Vamos presentar en una ventana emergente, el área de un triángulo, que me devolverá la función de nombre “areaTri”, a la que le pasaremos las dimensiones “base” en una variable y “altura” directamente con el valor 5. Los comentarios, en verde, ayudarán a comprender cada línea del código.

Observa que las variable “base” y el dato “5” son los parámetros que le pasamos a la función, sin embargo, la función espera las variables “a” y “b”. ¿Que significa esto?. Pues que tanto “a” como “b” quedan definidas como variables locales para la función “areaTri” y se les asignan los valores en el mismo orden que los entrega la llamada a la función; es decir, a la variable local “a” se le asigna el valor de la variable global “base” y a la local “b”, el dato “5”.
Comprendido qué es una función de JavaScript y como se utiliza, podemos ver qué es una “función anónima” de jQuery.

Funciones anónimas

Hemos visto que una función debe tener un nombre para poderla llamar con posterioridad. Pues bien, una función anónima es aquella que, efectivamente, NO tiene nombre.

Sintaxis:

function ()
{ //Grupo de instrucciones que realizará la función
}

Queda claro que no tienen nombre.

Llamada a la función:

¿Cómo podemos llamarla si no tiene nombre?, pues utilizándola toda ella como si fuera el nombre; es decir, encerrándola entre paréntesis y colocándole otro par de paréntesis al final. De esta forma, se autoejecutará. Se define y ejecuta al mismo tiempo.

(function(){ })();

¿Que ventajas tiene esto?. Básicamente dos:

  • Podemos pasar una función como parámetro a otra función que al ser “LOCAL” todo lo que dentro de la función anónima se defina, podemos tener la seguridad de que no se interferirá con otras funciones de la aplicación. Es lo que se denomina ENCAPSULAMIENTO.
  • Desde dentro de una función anónima, podemos llamar a una función nominal. Solo hay que tener presente la forma correcta de pasar parámetros, entre otros, el objeto “this” y el objeto “event” del evento desencadenado, con lo que podremos acceder a sus propiedades y métodos.

El ejemplo más claro que me viene a la mente es la forma de comenzar a trabajar con jQuery. No lo hace hasta que el DOM esté preparado, para así evitar errores al acceder a un elemento que todavía no estuviera “listo” (ready).

$(Document).ready(function(){
//Aquí va todo el código
});

Como puedes observar, “function” no lleva nombre y es la respuesta al evento “ready” de la página Web “Document”. Así podríamos seguir encapsulando todo lo que necesitáramos, con las ventajas ya comentadas.

<!DOCTYPE HTML>
<html>
<head>
 <title>Pruebas de eventos</title>
 <style>
  *{
  text-align: center;
  margin:auto;
  padding:3px;
  }
  #Pescadería{  width:500px;
    background-color: #888;
 }
 li{
    list-style-type: none;
  }
  ul{
    width: 250px;     background-color:#eee;
  }
  .bValor{
    border: 1px outset black;
    display:block;
  }
  </style>
   <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>   <script>
     $(document).ready(function(){//Función anónima
       $(".precio").on("click", function(e){//Función anónima /*La siguiente línea llama a una función nominal "prepes"y le pasa dos parámetros

        'e' es el "objeto evento" del manejador 'this' es el objeto sobre el que se ha realizado el evento        Esta es la forma de pasar estos parámetros a una

     función nominal */  prepes(e,this); //Llamada a la función nominal 'prepes'

       });

     //La variable "a" es global cuando se carge el DOM        var a="'a' es Global despues de cargar el DOM";        alert(a)        //La siguiente función ANÓNIMA se auto-ejecuta        //despues de carga en DOM con la siguiente sintaxis.

       (function(){//Función anónima autoejecutable           var a="'a' es Local dentro de una funcion anonima";           alert(a);        }());      });

     //Definición de la función NOMINAL 'prepes()'      function prepes(evento, objeto){         $(objeto).children("i").remove();//por si se ejecuta más de una vez         //Un comentario         $("<br><i style='background-color:#f11;'>Resulta algo caro</i>").appendTo(objeto);         alert("El filet de merluza cuesta: 1800 pesos/Kg." );         //Muestra el typo de evento que se ha producido         alert("El evento ha sido: " + evento.type +" ");         //Indica el valor de X en donde se produjo el evento clic         alert("El clic se produjo en la coordenada x= " + evento.pageX);      }  </script>  </head>  <body>    <div id="Pescadería">      <h1>Precios del pescado</h1>      <ul>        <li class="precio">          <h2>Filet de merluza</h2>          <button class="bValor">Comprobar</button>        </li>      </ul>    </div>     </body> </html>

Analiza y prueba antes este ejemplo. Igual te saca de dudas. He tratado de hacerlo lo más completo posible. Te pongo todo el código a continuación.

Si visitamos sitios sobre jQuery podremos comprobar que la sintaxis empleada es mucho más compacta que todos los ejemplos que venimos viendo. El objetivo de este tutorial es aprender jQuery de una forma sencilla, pero estaría inconcluso si no introducimos la forma más habitual de programar con jQuery (funciones anónimas y encadenamiento de llamadas con el objeto jQuery)

Veamos como se organiza nuestro código utilizando funciones anónimas.

Problema:Confeccionar una página que muestre dos títulos de primer nivel, al ser presionados cambiar el color de fuente, fondo y la fuente del texto.

pagina1.html

<!DOCTYPE html>
<html>
<head>
  <title>Ejemplo de jQuery</title>
  <meta charset="UTF-8">
</head>
<body>
  <h1 id="titulo1">Primer título</h1>
  <h1 id="titulo2">Segundo título</h1>
 
  <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
  <script src="func30.js"></script>
</body>

</html>

func30.js

let x = $(document);
x.ready(function () {
  let x = $("#titulo1");
  x.click(function () {
    let x = $("#titulo1");
    x.css("color", "#ff0000");
    x.css("background-color", "#ffff00");
    x.css("font-family", "Courier");
  });
  x = $("#titulo2");
  x.click(function () {
    let x = $("#titulo2");
    x.css("color", "#ffff00");
    x.css("background-color", "#ff0000");
    x.css("font-family", "Arial");
  });
})

Como podemos observar el código a quedado mucho más compacto. Normalmente uno utiliza funciones anónimos cuando el algoritmo contenido en la función solo se requiere para dicho evento.

La sintaxis para definir una función anónima:

x.ready(function(){
......
})

Como vemos llamamos al método ready y entre paréntesis incluimos la función tal como las venimos implementando en conceptos anteriores pero sin nombre.

También es interesante ver que podemos disponer otras funciones anónimos dentro de una función anónima:

  x.click(function () {
  ......
  });