Funciones flecha en JavaScript
En el anterior artículo vimos algunas de las novedades «recientes» en Javascript, concretamente las plantillas de cadena de texto, el operador spread y los parámetros rest. En este nuevo artículo veremos otra novedad contemporánea; las llamadas funciones flecha.
Las extrañas funciones flecha de JavaScript
Acostumbrados a las funciones convencionales, la primera vez que nos tropezamos con una función flecha puede resultar algo incómodo, ya que simplemente es otra forma diferente, y por lo tanto extraña, de declarar una función. Además, tienen el inconveniente añadido de que pueden adoptar formas muy variadas.
Su estructura mínima es la siguiente:
parámetros => cuerpo
Lo primero que nos llama la atención, es que ni tan siquiera parece código, ya que aunque se pueden indicar paréntesis para contener los parámetros y llaves para contener el cuerpo de la función; no siempre son necesarios. De hecho, otra cosa que tampoco es necesaria, es darle un nombre a la función.
Veamos una versión más completa;
var sumar = (a, b) => { return a+b; }
Esa función, sería lo mismo que esto;
function sumar(a, b) { return a+b; }
Como podéis ver, no es tan diferente. El problema, como ya he comentado, es que muchas partes son opcionales.
Las diferentes formas que pueden adoptar las funciones flecha
- No es necesario colocar los parámetros entre paréntesis si solo hay un parámetro.
var alCuadrado = a => { return a*a; } document.write(alCuadrado(3));
- Si solo tenemos una instrucción en el cuerpo no necesitamos usar las llaves. De hecho, si es el resultado de la función, nos podemos ahorrar el result.
var alCuadrado = a => a*a; document.write(alCuadrado(4));
- No es necesario darle un nombre a la función, de hecho, son funciones anónimas, no tienen nombre. Por lo que para invocar a la función, deberemos de guardarla en una variable que hará de nombre (tal y como se puede ver en los anteriores ejemplos), o bien usaremos otras formas de ejecutarla, como por ejemplo, pasar la función como parámetro de otra función (es decir, una callback).
function mostrarResultado(operacionA, operacionB) { document.write(operacionA()+operacionB()); } mostrarResultado(() => 2+2, () => 3*3);
También existe la posibilidad de declarar y ejecutar la función directamente. Para ello la colocaremos entre paréntesis y después colocaremos otro par de paréntesis vacíos como cuando llamamos a cualquier función.
(() => { alert("Hola!"); })();
- Para acabar de liarla, si lo que queremos es devolver un objeto, pero no queremos usar la palabra clave return, deberemos de usar paréntesis para contener el objeto devuelto.
var calculos = (a,b) => ( {suma:a+b, resta:a-b, mult:a*b} ) document.write(JSON.stringify(calculos(3,2)));
Y básicamente ya está. No hay mucho más que añadir. Tan solo tenéis que tener en cuenta que no se pueden usar como funciones constructoras de objetos.
¿Para qué sirve esta nueva forma tan rebuscada de escribir una función?
Pues básicamente es una forma más moderna (y se supone que más elegante y breve) de escribir funciones.
¿Solo sirven para eso?
En realidad no, ya que también sirven para resolver un problema clásico de JavaScript con la palabra clave this.
¿En que consiste este problema? Lo mejor es que veamos un ejemplo: un código como el siguiente, debería de funcionar, pero no lo hace.
function Mensaje(msg){ this.msg=msg; this.mostrar=function(){ alert(this.msg); }; } var x = new Mensaje("Hola mundo!"); var metodo = x.mostrar; x.mostrar(); // si funciona metodo(); // no funciona (y debería)
Una forma de solucionar este problema es con el método bind, que nos permite indicar quien hará el papel de this. Como en nuestro caso queremos que sea el propio objeto, la asignación de la variable método la realizaríamos de este modo;
var metodo = x.mostrar.bind(x);
Lo cual no es ni muy limpio, ni muy intuitivo, la verdad (de hecho, no deja de ser una chapucilla). Si usamos una función flecha, por el contrario, el código funciona tal y como era de esperar sin necesidad de usar el método bind.
function Mensaje(msg){ this.msg=msg; this.mostrar = () => { alert(this.msg); }; } var x = new Mensaje("Hola mundo!"); var metodo = x.mostrar; x.mostrar(); // si funciona metodo(); // también funciona tal y como sería de esperar
No voy entrar en los detalles de porque se produce este problema, pero podéis encontrar más información en los enlaces anteriores. El tema es que este problema puede resultar bastante molesto, por lo que cuando os surja, ya sabéis como solventarlo. Tened en cuenta que el ejemplo no es la única forma en la que se manifiesta el problema, pero siempre consiste en lo mismo, en la dificultad para acceder a un this que realmente haga referencia al objeto (tal y como sería de esperar).
Las amistades de verdad requieren tiempo
Así que nada, si alguna vez os encontráis con => en un código JavaScript ya sabéis de que se trata. Personalmente no soy muy fan debido a las múltiples formas que pueden adoptar (prefiero escribir un poco más y tener código más legible), pero es cierto que para casos como el problema del this, las funciones flecha permiten un código más limpio y claro. Supongo que con el tiempo y la costumbre me iré familiarizando con esta nueva sintaxis y quién sabe, tal vez les coja cariño y todo.