Las funciones flecha, introducidas en ES6, no son solo una forma más corta de escribir funciones. Tienen diferencias semánticas importantes con las funciones declaradas con function: no tienen su propio this, no tienen arguments, no pueden ser constructores y no se pueden usar como generadores. Conocer cuándo usarlas y cuándo evitarlas es lo que marca la diferencia.
Sintaxis: de larga a compacta
Las funciones flecha permiten escribir funciones de una forma más concisa, especialmente cuando el cuerpo es una sola expresión:
// Función tradicional
function sumar(a, b) {
return a + b;
}
// Arrow function equivalente
const sumarFlecha = (a, b) => a + b;
// Con un solo parámetro, los paréntesis son opcionales
const doble = x => x * 2;
// Sin parámetros, los paréntesis son obligatorios
const saludar = () => 'Hola';
// Cuerpo con bloque: necesita return explícito
const clamp = (val, min, max) => {
if (val < min) return min;
if (val > max) return max;
return val;
};
// Devolver un objeto literal: envolver en paréntesis
const crearUsuario = (nombre, edad) => ({ nombre, edad });
console.log(crearUsuario('Ana', 30)); // {nombre: 'Ana', edad: 30}
// Sin paréntesis, las llaves se interpretan como bloque
La diferencia clave: this léxico
Las funciones flecha capturan el this del scope donde se definen (léxico), en lugar de determinarlo en el momento de la llamada. Esto las hace perfectas para callbacks donde necesitas preservar el contexto:
// Bug con function tradicional:
class Temporizador {
constructor() {
this.segundos = 0;
}
iniciar() {
setInterval(function() {
this.segundos++; // ERROR: this es window/undefined
}, 1000);
}
}
// Correcto con arrow function:
class TemporizadorCorrecto {
constructor() {
this.segundos = 0;
}
iniciar() {
setInterval(() => {
this.segundos++; // this es la instancia de TemporizadorCorrecto
console.log(this.segundos);
}, 1000);
}
}
// También en promesas:
class ApiService {
constructor(url) {
this.url = url;
}
obtenerDatos() {
return fetch(this.url)
.then(r => r.json()) // this heredado
.then(datos => {
console.log(this.url, datos); // this heredado
return datos;
});
}
}
No tienen arguments
Las funciones flecha no tienen su propio objeto arguments. Si necesitas argumentos variables en una arrow function, usa rest parameters:
function tradicional() {
console.log(arguments); // Arguments [1, 2, 3]
}
tradicional(1, 2, 3);
const flecha = () => {
console.log(arguments); // ReferenceError (o arguments del scope externo)
};
// Correcto: usar rest
const flechaRest = (...args) => {
console.log(args); // [1, 2, 3] array real
return args.reduce((a, b) => a + b, 0);
};
console.log(flechaRest(1, 2, 3)); // 6
No se pueden usar como constructores
Las funciones flecha no tienen un [[Construct]] interno. Intentar usarlas con new lanza un TypeError:
const Persona = (nombre) => {
this.nombre = nombre;
};
const p = new Persona('Ana'); // TypeError: Persona is not a constructor
// Para constructores, usa function o class:
class PersonaClase {
constructor(nombre) {
this.nombre = nombre;
}
}
Cuándo NO usar funciones flecha
Hay contextos donde las arrow functions son una mala elección:
// MAL: método de objeto (this no apunta al objeto)
const objeto = {
valor: 42,
obtener: () => this.valor // this es el global, no objeto
};
console.log(objeto.obtener()); // undefined
// BIEN: method shorthand
const objetoCorrecto = {
valor: 42,
obtener() { return this.valor; }
};
// MAL: event listener donde necesitas this como elemento DOM
boton.addEventListener('click', () => {
this.style.color = 'red'; // this no es el botón
});
// BIEN: function tradicional
boton.addEventListener('click', function() {
this.style.color = 'red'; // this es el botón
});
// MAL: métodos de prototipo si usan this
Array.prototype.doble = () => this.map(x => x * 2);
// BIEN:
Array.prototype.doble = function() { return this.map(x => x * 2); };
La guía práctica: usa arrow functions para callbacks, métodos de array (map, filter, etc.), funciones de utilidad puras y cualquier lugar donde necesites preservar el this externo. Usa function para métodos de objeto, constructores, manejadores de eventos que necesiten this y funciones que usen arguments.
