Repasemos las funciones de flecha.
Las funciones de flecha no son sólo una “taquigrafía” para escribir cosas pequeñas. Tienen algunas características muy específicas y útiles.
JavaScript está lleno de situaciones en las que necesitamos escribir una pequeña función que se ejecuta en otro lugar.
Por ejemplo:
arr.forEach(func)
: forEach
ejecuta func
para cada elemento de la matriz.
setTimeout(func)
: func
la ejecuta el programador integrado.
…hay más.
Está en el espíritu mismo de JavaScript crear una función y pasarla a alguna parte.
Y en este tipo de funciones normalmente no queremos salir del contexto actual. Ahí es donde las funciones de flecha resultan útiles.
Como recordamos del capítulo Métodos de objeto, "esto", las funciones de flecha no tienen this
. Si se accede this
, se toma desde el exterior.
Por ejemplo, podemos usarlo para iterar dentro de un método de objeto:
dejar grupo = { título: "Nuestro grupo", estudiantes: ["John", "Pete", "Alice"], mostrarLista() { esto.estudiantes.paraCada( estudiante => alerta(este.título + ': ' + estudiante) ); } }; grupo.showList();
Aquí, en forEach
, se usa la función de flecha, por lo que this.title
es exactamente igual que en el método externo showList
. Es decir: group.title
.
Si usáramos una función “normal”, habría un error:
dejar grupo = { título: "Nuestro grupo", estudiantes: ["John", "Pete", "Alice"], mostrarLista() { this.students.forEach(función(estudiante) { // Error: no se puede leer la propiedad 'título' de indefinido alerta(este.título + ': ' + estudiante); }); } }; grupo.showList();
El error se produce porque forEach
ejecuta funciones con this=undefined
de forma predeterminada, por lo que se intenta acceder a undefined.title
.
Eso no afecta las funciones de flecha, porque simplemente no tienen this
.
Las funciones de flecha no se pueden ejecutar con new
Naturalmente, no tener this
significa otra limitación: las funciones de flecha no se pueden usar como constructores. No se les puede llamar con new
.
Funciones de flecha VS vinculación
Hay una diferencia sutil entre una función de flecha =>
y una función normal llamada con .bind(this)
:
.bind(this)
crea una "versión enlazada" de la función.
La flecha =>
no crea ningún enlace. La función simplemente no tiene this
. La búsqueda de this
se realiza exactamente de la misma manera que una búsqueda de variables normal: en el entorno léxico externo.
Las funciones de flecha tampoco tienen arguments
variables.
Eso es genial para los decoradores, cuando necesitamos reenviar una llamada con los arguments
this
y actuales.
Por ejemplo, defer(f, ms)
obtiene una función y devuelve un contenedor alrededor de ella que retrasa la llamada en ms
milisegundos:
función diferir(f, ms) { función de retorno() { setTimeout(() => f.apply(esto, argumentos), ms); }; } función decir Hola (quién) { alert('Hola, ' + quién); } let sayHolaDeferred = aplazar(sayHola, 2000); decirHolaDeferido("Juan"); // Hola, John después de 2 segundos
Lo mismo sin una función de flecha se vería así:
función diferir(f, ms) { función de retorno (... argumentos) { sea ctx = esto; setTimeout(función() { devolver f.apply(ctx, args); }, EM); }; }
Aquí tuvimos que crear variables adicionales args
y ctx
para que la función dentro de setTimeout
pudiera tomarlas.
Funciones de flecha:
no tengo this
no tener arguments
No se puede llamar con new
Tampoco tienen super
, pero aún no lo estudiamos. Lo haremos en el capítulo Herencia de clases.
Esto se debe a que están destinados a fragmentos cortos de código que no tienen su propio "contexto", sino que funcionan en el actual. Y realmente brillan en ese caso de uso.