Funciones flecha en JavaScript
Aprende cómo funcionan las funciones flecha en JavaScript: this léxico, sin arguments ni super propios, por qué no pueden ser constructores y cuándo no usarlas en métodos de objetos o prototipos.
Introducción a las funciones flecha en JavaScript
Las funciones flecha, introducidas en ES6 (ECMAScript 2015), son hoy una característica fundamental de JavaScript que ofrece una forma más sencilla de escribir expresiones de función. Son especialmente populares porque simplifican el código y ayudan a resolver problemas comunes con la palabra clave this.
Esta página va más allá de la sintaxis (cubierta en Funciones flecha, los conceptos básicos) y profundiza en el por qué de su comportamiento. En resumen, una función flecha no tiene sus propios enlaces. No obtiene su propio this, sus propios arguments, su propio super, ni un método [[Construct]]. Cada vez que se hace referencia a cualquiera de estos dentro de una función flecha, JavaScript los busca en el ámbito circundante (léxico), exactamente igual que haría con cualquier variable ordinaria. Casi todas las peculiaridades y ventajas de las funciones flecha se derivan de esa única regla.
Definición de funciones flecha
Las funciones flecha permiten una sintaxis más corta en comparación con las expresiones de función tradicionales. A continuación se muestra una comparación básica:
La versión con función flecha no solo es más corta, sino que también elimina la necesidad de la palabra clave function y las llaves cuando hay una única expresión.
Variaciones de sintaxis
Las funciones flecha se pueden escribir de distintas formas según el número de parámetros y la complejidad del cuerpo de la función:
- Sin parámetros: Se usan paréntesis vacíos:
- Un solo parámetro: Los paréntesis son opcionales:
- Varios parámetros: Los paréntesis son obligatorios:
- Varias líneas: Se usan llaves y un
returnexplícito (si se devuelve un valor):
Las funciones flecha no tienen su propio this
La propiedad más importante de las funciones flecha es que no obtienen su propio this. Una función normal determina su this en el momento de la llamada según cómo se invoca (cubierto en Métodos de objeto, "this"). Una función flecha ignora todo eso y lee this del ámbito donde fue definida: esto se llama this léxico.
Esto es exactamente lo que se necesita cuando una función flecha se usa como callback. Un método que pierde su this dentro de un callback ordinario lo conserva dentro de una función flecha:
Si se reemplaza la función flecha por una function(member) { ... } normal, el this dentro de forEach pasa a ser undefined, lanzando Cannot read properties of undefined. Antes de las funciones flecha, los desarrolladores usaban const self = this; o .bind(this) como alternativa — ver Enlace de funciones. Las funciones flecha eliminan la necesidad de esas soluciones.
La misma regla léxica resuelve el clásico problema del temporizador, donde un callback se ejecuta desvinculado de su objeto:
Dado que this está fijado léxicamente, no se puede cambiar. Llamar a .call(), .apply() o .bind() sobre una función flecha no tiene efecto sobre this — el enlace se ignora:
Las funciones flecha no tienen arguments
Las funciones flecha tampoco tienen su propio objeto arguments. Al hacer referencia a arguments dentro de una función flecha, se accede al de la función envolvente, lo cual resulta útil para envoltorios y decoradores:
Si realmente se necesitan los argumentos de la propia función flecha, se usan los parámetros rest (...args), que funcionan en cualquier contexto:
Las funciones flecha no se pueden usar como constructores
Dado que una función flecha no tiene el método interno [[Construct]] ni la propiedad prototype, no se puede utilizar con el operador new:
Por la misma razón, las funciones flecha no pueden hacer referencia a super para acceder a una clase padre, por lo que nunca se usan como constructores de clases ni como métodos de clase que dependan de super.
Cuándo no usar funciones flecha
El this léxico es ideal en callbacks, pero resulta incorrecto en algunos contextos habituales. Usa una función normal cuando la función necesite su propio this dinámico.
Métodos de objeto
Cuando una función es el método de un object, normalmente se espera que this apunte a ese object. Una función flecha toma this del ámbito exterior (con frecuencia el módulo o el ámbito global), por lo que no verá las propiedades propias del object:
Usa la forma abreviada de método normal (o una expresión function) para los métodos de objeto. Consulta Métodos de objeto, "this" para ver la imagen completa.
Métodos de prototipo y constructores
Dado que las funciones flecha no se pueden usar como constructores y no tienen su propio this, no pueden definir métodos de prototipo ni servir como funciones constructoras. Los métodos añadidos a un prototipo deben ser funciones normales para que cada instancia resuelva this hacia sí misma.
Manejadores de eventos DOM (en el navegador)
Cuando se adjunta un manejador con addEventListener, el navegador lo llama con this apuntando al elemento que recibió el evento. Una función flecha ignora esto y conserva el this exterior, por lo que debes usar una función normal si necesitas que this sea el elemento (siempre puedes usar event.currentTarget en cualquier caso).
Técnicas avanzadas
Retornar literales de object
Para retornar un literal de object desde una función flecha, envuelve el object entre paréntesis:
IIFE con funciones flecha
Las funciones flecha se pueden usar para crear Expresiones de Función Invocadas Inmediatamente (IIFE):
Resumen
Las funciones flecha se entienden mejor por lo que carecen. No tienen:
- Propio
this— se toma del ámbito circundante (thisléxico), y.call/.apply/.bindno pueden cambiarlo. Ideal para callbacks, incorrecto para métodos de objeto. - Propios
arguments— usa parámetros rest (...args) si los necesitas. super— por lo que no pueden ser métodos de clase que llamen a un padre.[[Construct]]niprototype— por lo que no pueden usarse connewni como métodos de prototipo.
Usa funciones flecha para callbacks cortos y cualquier función que deba conservar su this exterior. Usa funciones normales para métodos de objeto, métodos de prototipo, constructores y manejadores DOM que necesiten un this dinámico.
Capítulos relacionados
- Funciones flecha, los conceptos básicos
- Métodos de objeto, "this"
- Enlace de funciones
- Constructor, operador "new"
- Parámetros rest y sintaxis spread