Las funciones flecha o arrow functions son funciones con una sintaxis más compacta que aparecieron en ECMAScript 6. Todos acordamos en que su sintaxis es más 'linda' que las funciones que veniamos viendo pero... ¿se agregaron solo por una cuestión estética?
En este post no voy a entrar en detalle en la sintaxis de las arrow functions sino que voy a hacer hincapié en una de sus principales diferencias con las tradicionales. Las arrow functions fueron creadas para simplificar el scope de las funciones y hacer uso de la palabra reservada this de una manera más clara. Pero ¿ Qué significa esto ? Vamos a un ejemplo.
Supongamos que tenemos un objeto 'persona' que tiene como atributo 'nombre' y valor 'Agustin', también tiene una función que loguea por consola el nombre (nótese que el ejemplo es de una función tradicional):
const persona = { nombre: 'Agustin', decirNombre(){ console.log(this.name) } } console.log(persona.decirNombre()) // OUTPUT : 'Agustin'
Como esperabamos... nada raro. Ahora probemos lo mismo pero con una funcion flecha:
const persona = { nombre: 'Agustin', decirNombre: function() { console.log(this.nombre) } decirNombreFuncionFlecha: () => { console.log(this.nombre) } } persona.decirNombreFuncionFlecha(); // OUTPUT : undefined
¿Qué paso?
Para explicarlo repasemos que es esa palabra reservada this... THIS es el objeto contexto de Javascript
en el cual se está ejecutando el código actual. En el caso de la función regular, this hace referencia
al objeto desde el que se llamo a la funcion 'decirNombre', o sea al objeto persona. Si hacemos un console log de this dentro de la función decirNombre veremos que por consola this es nuestro objeto persona.
Dicho esto, nos queda ver porqué con la función flecha no estamos teniendo el mismo resultado.
Lo que ocurre es que las arrow functions, a diferencia de las funciones regulares, no se les asigna un this propio sino que
heredan el this del contexto superior, que estando dentro del contexto del objeto persona, this hace referencia al objeto window. Por lo tanto, la propiedad 'nombre' no esta definida en el objeto window, y recibimos el mensaje undefined.
Si las arrow function nos trae problemas, en este caso, al acceder al objeto this, entonces ¿cuál es el beneficio de usarlas?.
Vamos a un ejemplo en donde sea beneficioso utilizarlas. Agreguemosle a nuestro escenario original que el nombre se loguee en consola luego de 3 segundos llamada la función
'decirNombre'. Para esto, vamos a utilizar la función de window 'setTimeout' y le vamos a pasar una función anónima regular como parámetro.
Algo así:
const persona = { nombre: 'Agustin', decirNombre: function() { setTimeout(function(){ console.log(this.nombre); }, 3000); } } persona.decirNombre(); // OUTPUT : UNDEFINED
OOPS! De nuevo undefined, pero ¿por qué?. Recordemos que las funciones regulares le asignan al this un objeto dependiendo en dónde son 'llamadas', y en este caso está siendo pasada como un callback, o sea que es llamada dentro del contexto de setTimeout, y este último al ser una función del objeto window this tiene un valor de 'window'. Una solución antes de las funciones flechas era asignarle a una variable la referencia this' dentro del contexto deseado para luego usarla dónde la necesitamos, quedaría así:
const persona = { nombre: 'Agustin', decirNombre: function() { let that = this; // en está parte de la función 'this' hace referencia a nuestro objeto persona setTimeout(function(){ console.log(that.nombre); }, 3000); } } persona.decirNombre(); // OUTPUT : Agustin
Genial!!!. Pero no estaríamos aprovechando la linda solución de las arrow functions que vienen a suplir el problema de referencia de this. Reemplazando la función dentro de setTimeout por una arrow function bastaría para que siga funcionando, es más, no necesitamos esa variable auxiliar que agregamos.
const persona = { nombre: 'Agustin', decirNombre: function() { setTimeout(() => { console.log(this.nombre); }, 3000); } }
TA DAN!!!!!
Para darle un cierre al artículo, voy a comentar porqué el this en la función flecha hace referencia al objeto persona. Dijimos que las arrow functions no tienen su propio this sino que lo heredan del contexto superior, que en este caso vendría a ser la función decirNombre, y dentro de este contexto this apunta al objeto que llama a dicha función, o sea persona. Por lo tanto this dentro de la arrow function apunta a persona :)