Funciones de flecha (Arrow Function)
Al finalizar este tema
Podrás utilizar libremente la sintaxis de las funciones de flecha, explicar la diferencia clave con las funciones normales (la vinculación de this) y decidir cuándo usarlas y cuándo evitarlas.
De la palabra clave function a las flechas
Antes de ES6, siempre se utilizaba la palabra clave function para crear funciones:
const add = function(a, b) {
return a + b;
};Si lo cambiamos a una función flecha:
const add = (a, b) => {
return a + b;
};Si el cuerpo consiste únicamente en una expresión, se pueden omitizar las llaves y la palabra clave return:
const add = (a, b) => a + b;Si solo hay un parámetro, también se pueden omitir los paréntesis:
const double = x => x * 2;Resumen de las variantes gramaticales
// Sin parámetros: los paréntesis son obligatorios
const greet = () => "Hola";
// Un parámetro: los paréntesis se pueden omitir
const square = x => x * x;
// Dos o más parámetros: los paréntesis son obligatorios
const sum = (a, b) => a + b;
// Cuerpo de varias líneas: se requieren llaves y return
const calculate = (a, b) => {
const result = a * b;
console.log(result);
return result;
};
// Al devolver un objeto: envolverlo entre paréntesis
const makeUser = (name) => ({ name: name, role: "user" });El último patrón suele causar confusión. Si se usa { name: name } tal cual, JavaScript lo interpreta como las llaves del cuerpo de una función. Es necesario envolverlo entre paréntesis () para indicar "esto es un objeto literal".
Las funciones flecha brillan en los callbacks
Al usarlas como callbacks para métodos de arrays, las funciones flecha son la opción más natural:
const numbers = [1, 2, 3, 4, 5];
// Función normal
const doubled = numbers.map(function(n) {
return n * 2;
});
// Función flecha
const doubled = numbers.map(n => n * 2);En los métodos de arreglos como filter, reduce, forEach, sort, etc., usar la palabra clave function en cada caso hace que el código sea más largo y oculta la lógica principal. Esta es la razón principal por la que se adoptaron las funciones flecha.
// Patrón práctico: encadenamiento
const result = users
.filter(u => u.age >= 18)
.map(u => u.name)
.sort((a, b) => a.localeCompare(b));this — la diferencia más importante
El this de una función normal se determina según el modo de invocación. El this de una función flecha se determina en el lugar de declaración:
const timer = {
seconds: 0,
// ❌ Función normal: this apunta a window
startBroken: function() {
setInterval(function() {
this.seconds++; // this === window (o undefined en modo estricto)
console.log(this.seconds); // NaN
}, 1000);
},
// ✅ Función flecha: this apunta al objeto timer
start: function() {
setInterval(() => {
this.seconds++; // this === timer
console.log(this.seconds); // 1, 2, 3...
}, 1000);
}
};Al pasar una función normal a setInterval, el objeto global (window) se convierte en this cuando esa función se ejecuta. Que el this de la devolución de llamada difiera de lo esperado fue una de las mayores trampas de JavaScript.
Las funciones flecha no crean su propio this. En su lugar, utilizan directamente el this del ámbito exterior en el que se declararon. Esto se conoce como this léxico.
Antes de ES6, para evitar este problema se utilizaban var self = this; o .bind(this):
// Solución alternativa de la época de ES5
start: function() {
var self = this;
setInterval(function() {
self.seconds++;
}, 1000);
}Las funciones flecha han reemplazado completamente este patrón.
Dónde no se deben usar funciones flecha
1. Métodos de objetos
const user = {
name: "Carlos",
// ❌ Función flecha: this no es user
greet: () => {
console.log(`Hola, ${this.name}`); // undefined
},
// ✅ Sintaxis abreviada de función normal: this es user
greet() {
console.log(`Hola, ${this.name}`); // "Hola, Carlos"
}
};Si se utiliza una función flecha como método de un objeto literal, this no apunta al objeto, sino al ámbito externo (generalmente el global).
2. Constructor
// ❌ Una función flecha no puede ser constructora
const Person = (name) => { this.name = name; };
new Person("Carlos"); // TypeError: Person is not a constructorLas funciones flecha no tienen prototype, por lo que no se puede usar la palabra clave new.
3. Cuando se necesita this en un controlador de eventos del DOM
// ❌ Función flecha: this no es el botón
button.addEventListener("click", () => {
this.classList.toggle("active"); // this !== button
});
// ✅ Función normal: this es el elemento que recibe el evento
button.addEventListener("click", function() {
this.classList.toggle("active"); // this === button
});Sin embargo, como pueden reemplazarse por event.target o event.currentTarget, en muchos casos es válido utilizar funciones flecha.
Lo que no tienen las funciones flecha
| Funcionalidad | Función normal | Función flecha |
|---|---|---|
this propio | ✅ | ❌ (léxico) |
Objeto arguments | ✅ | ❌ |
Llamada con new (constructor) | ✅ | ❌ |
prototype | ✅ | ❌ |
super | ✅ | ❌ (léxico) |
En lugar de arguments, se utilizan parámetros rest (...args):
// Función normal
function sum() {
return [...arguments].reduce((a, b) => a + b, 0);
}
// Función flecha
const sum = (...args) => args.reduce((a, b) => a + b, 0);...args es más explícito que arguments y permite usar directamente los métodos de array, por lo que se recomienda el enfoque de las funciones flecha.
Criterios de evaluación
¿Es una función callback? → Función flecha
¿Se usa en un método de array (map/filter/...)? → Función flecha
¿Es un método de un objeto? → Función normal (sintaxis abreviada)
¿Se necesita un constructor? → Función normal (o class)
¿Hay que cambiar this dinámicamente? → Función normalIdea clave: Usa funciones flecha para
() => {}y conserva elthisdel ámbito léxico circundante (this léxico). Recuerda: usa funciones flecha en callbacks y funciones normales en métodos de objetos.