Funciones de Flecha Revisadas
Las funciones de flecha no son solo una manera de escribir menos para funciones pequeñas. Tienen características específicas que las hacen especialmente útiles en ciertas situaciones.
JavaScript a menudo requiere la creación de pequeñas funciones que se ejecutan en diferentes contextos. Por ejemplo:
arr.forEach(func)
–func
se ejecuta para cada elemento del arreglo.setTimeout(func)
–func
se ejecuta después de un tiempo determinado.- …y muchas más.
En estas funciones, usualmente queremos que el contexto actual se mantenga. Aquí es donde las funciones de flecha brillan.
Las Funciones de Flecha no Tienen this
Como vimos en el capítulo de Métodos de Objeto, «this», las funciones de flecha no tienen su propio this
. En su lugar, toman el this
del contexto en el que fueron creadas.
Por ejemplo, podemos usarlas para iterar dentro de un método de objeto:
let grupo = {
titulo: "Nuestro Grupo",
estudiantes: ["Juan", "Pedro", "Alicia"],
mostrarLista() {
this.estudiantes.forEach(
estudiante => alert(this.titulo + ': ' + estudiante)
);
}
};
grupo.mostrarLista();
Aquí, en forEach
, usamos una función de flecha, así que this.titulo
es igual que en el método externo mostrarLista
. Es decir, grupo.titulo
.
Si hubiéramos usado una función «normal», habría un error:
let grupo = {
titulo: "Nuestro Grupo",
estudiantes: ["Juan", "Pedro", "Alicia"],
mostrarLista() {
this.estudiantes.forEach(function(estudiante) {
// Error: No se puede leer la propiedad 'titulo' de undefined
alert(this.titulo + ': ' + estudiante);
});
}
};
grupo.mostrarLista();
El error ocurre porque forEach
ejecuta funciones con this = undefined
por defecto, por lo que intenta acceder a undefined.titulo
.
Eso no afecta a las funciones de flecha porque simplemente no tienen this
.
Las Funciones de Flecha no Pueden Usarse con new
No tener this
significa otra limitación: las funciones de flecha no pueden usarse como constructores. No se pueden invocar con new
.
Funciones de Flecha vs bind
Hay una diferencia sutil entre una función de flecha =>
y una función regular llamada con .bind(this)
:
.bind(this)
crea una “versión ligada” de la función.- La flecha
=>
no crea ningún enlace. La función simplemente no tienethis
. La búsqueda dethis
se realiza de la misma manera que la búsqueda de una variable regular: en el entorno léxico externo.
Las Flechas no Tienen arguments
Las funciones de flecha tampoco tienen la variable arguments
.
Esto es genial para los decoradores, cuando necesitamos reenviar una llamada con el this
y arguments
actuales.
Por ejemplo, defer(f, ms)
recibe una función y devuelve un contenedor que retrasa la llamada en ms
milisegundos:
function defer(f, ms) {
return function() {
setTimeout(() => f.apply(this, arguments), ms);
};
}
function decirHola(quien) {
alert('Hola, ' + quien);
}
let decirHolaAplazado = defer(decirHola, 2000);
decirHolaAplazado("Juan"); // Hola, Juan después de 2 segundos
Lo mismo sin una función de flecha se vería así:
function defer(f, ms) {
return function(...args) {
let ctx = this;
setTimeout(function() {
return f.apply(ctx, args);
}, ms);
};
}
Aquí tuvimos que crear las variables adicionales args
y ctx
para que la función dentro de setTimeout
pudiera usarlas.
Resumen
Las funciones de flecha:
- No tienen
this
. - No tienen
arguments
. - No se pueden llamar con
new
. - Tampoco tienen
super
, algo que veremos en el capítulo de Herencia de Clases.
Estas características se deben a que están diseñadas para pequeñas piezas de código que no tienen su propio «contexto», sino que funcionan en el contexto actual. Y realmente sobresalen en ese caso de uso.