La pregunta está dirigida a personas que han pensado en el estilo de código en el contexto del próximo ECMAScript 6 (Harmony) y que ya han trabajado con el lenguaje.
Con () => {}
y function () {}
estamos obteniendo dos formas muy similares de escribir funciones en ES6. En otros idiomas, las funciones lambda a menudo se distinguen por ser anónimas, pero en ECMAScript cualquier función puede ser anónima. Cada uno de los dos tipos tiene dominios de uso únicos (es decir, cuándo this
debe vincularse explícitamente o no explícitamente). Entre esos dominios hay una gran cantidad de casos en los que cualquier notación servirá.
Las funciones de flecha en ES6 tienen al menos dos limitaciones:
- No funciona
new
y no se puede usar al crearprototype
- Fijo
this
vinculado al alcance en la inicialización
Dejando a un lado estas dos limitaciones, las funciones de flecha teóricamente podrían reemplazar las funciones regulares en casi cualquier lugar. ¿Cuál es el enfoque correcto usándolos en la práctica? ¿Deben usarse las funciones de flecha, por ejemplo:
- "en todas partes funcionan", es decir, en todas partes una función no tiene que ser independiente de la
this
variable y no estamos creando un objeto. - solo "en todas partes donde se necesitan", es decir, oyentes de eventos, tiempos de espera, que deben estar sujetos a un determinado alcance
- con funciones 'cortas' pero no con funciones 'largas'
- solo con funciones que no contienen otra función de flecha
Lo que estoy buscando es una guía para seleccionar la notación de función apropiada en la versión futura de ECMAScript. La directriz deberá ser clara, de modo que pueda enseñarse a los desarrolladores de un equipo, y ser coherente para que no requiera una refactorización constante de una notación de función a otra.
Fixed this bound to scope at initialisation
como una limitación?this
es algo que puede hacer con funciones regulares pero no con funciones de flecha.Fixed this bound to scope at initialisation
sea una limitación. :) Echa un vistazo a este artículo: exploringjs.com/es6/ch_arrow-functions.htmlRespuestas:
Hace un tiempo, nuestro equipo migró todo su código (una aplicación AngularJS de tamaño medio) a JavaScript compilado usando
TraceurBabel . Ahora estoy usando la siguiente regla general para las funciones en ES6 y más allá:function
en el ámbito global y paraObject.prototype
propiedades.class
para constructores de objetos.=>
cualquier otro lugar.¿Por qué usar las funciones de flecha en casi todas partes?
thisObject
que la raíz. Si incluso una única devolución de llamada de función estándar se combina con un montón de funciones de flecha, existe la posibilidad de que el alcance se confunda.function
sobresale inmediatamente para definir el alcance. Un desarrollador siempre puede buscar la siguientefunction
declaración más alta para ver cuálthisObject
es.¿Por qué usar siempre funciones regulares en el alcance global o alcance del módulo?
thisObject
.window
objeto (alcance global) se aborda mejor explícitamente.Object.prototype
definiciones viven en el ámbito global (pensar,String.prototype.truncate
etc.) y, en general, esas tienen que ser del tipofunction
. El uso constantefunction
en el ámbito global ayuda a evitar errores.function foo(){}
queconst foo = () => {}
, en particular, fuera de otras llamadas a funciones. (2) El nombre de la función se muestra en las trazas de la pila. Si bien sería tedioso nombrar cada devolución de llamada interna, nombrar todas las funciones públicas es probablemente una buena idea.Constructores de objetos
Intentar instanciar una función de flecha produce una excepción:
Por lo tanto, una ventaja clave de las funciones sobre las funciones de flecha es que las funciones funcionan como constructores de objetos:
Sin embargo, la definición de clase de borrador 2 ES Harmony funcionalmente idéntica es casi tan compacta:
Espero que el uso de la notación anterior eventualmente se desaliente. Algunos todavía pueden usar la notación de constructor de objetos para fábricas de objetos anónimos simples donde los objetos se generan mediante programación, pero no para mucho más.
Cuando se necesita un constructor de objetos, se debe considerar convertir la función a a
class
como se muestra arriba. La sintaxis también funciona con funciones / clases anónimas.Legibilidad de las funciones de flecha
Probablemente el mejor argumento para apegarse a las funciones regulares (maldita sea la seguridad del alcance) sería que las funciones de flecha son menos legibles que las funciones regulares. Si su código no es funcional en primer lugar, entonces las funciones de flecha pueden no parecer necesarias, y cuando las funciones de flecha no se usan consistentemente, se ven feas.
ECMAScript ha cambiado bastante desde que ECMAScript 5.1 nos dio el funcional
Array.forEach
,Array.map
y todas estas características de programación funcional que nos hacen usar funciones donde antes se habrían usado bucles for. JavaScript asíncrono ha despegado bastante. ES6 también enviará unPromise
objeto, lo que significa aún más funciones anónimas. No hay vuelta atrás para la programación funcional. En JavaScript funcional, las funciones de flecha son preferibles a las funciones regulares.Tomemos, por ejemplo, este (particularmente confuso) fragmento de código 3 :
El mismo código con funciones regulares:
Si bien cualquiera de las funciones de flecha se puede reemplazar por una función estándar, sería muy poco lo que ganaría al hacerlo. ¿Qué versión es más legible? Yo diría el primero.
Creo que la pregunta de si usar funciones de flecha o funciones regulares será menos relevante con el tiempo. La mayoría de las funciones se convertirán en métodos de clase, que eliminan la
function
palabra clave, o se convertirán en clases. Las funciones permanecerán en uso para parchear clases a través deObject.prototype
. Mientras tanto, sugiero reservar lafunction
palabra clave para cualquier cosa que realmente debería ser un método de clase o una clase.Notas
extend
palabra clave. Una diferencia menor es que las declaraciones de clase son constantes, mientras que las declaraciones de funciones no lo son.fuente
function
es cuando no quieresthis
estar atado, ¿verdad? Mi escenario más común para esto son los eventos, donde es posible que deseethis
hacer referencia al objeto (generalmente nodo DOM) que activó el evento.=>
termina viéndose mejor con el tiempo. Dudo que los no programadores sientan de manera muy diferente los dos ejemplos. Si está escribiendo el código ES2016, normalmente tampoco terminará usando tantas funciones de flecha. En este ejemplo, usando async / await y una comprensión de matriz, terminaría con solo una función de flecha en lareduce()
llamada.Según la propuesta , las flechas apuntaban "a abordar y resolver varios puntos de dolor comunes de los tradicionales
Function Expression
". Tenían la intención de mejorar las cosas mediante la vinculaciónthis
léxica y ofreciendo una sintaxis concisa.Sin embargo,
this
léxicoPor lo tanto, las funciones de flecha crean oportunidades para la confusión y los errores, y deben excluirse del vocabulario de un programador de JavaScript, reemplazarse
function
exclusivamente.En cuanto a léxico
this
this
es problemático:Las funciones de flecha intentan solucionar el problema donde necesitamos acceder a una propiedad
this
dentro de una devolución de llamada. Ya hay varias formas de hacerlo: se podría asignarthis
a una variable, usarbind
o usar el tercer argumento disponible en losArray
métodos agregados. Sin embargo, las flechas parecen ser la solución más simple, por lo que el método podría refactorizarse así:Sin embargo, considere si el código usó una biblioteca como jQuery, cuyos métodos se unen
this
especialmente. Ahora, hay dosthis
valores con los que lidiar:Debemos usar
function
paraeach
unirthis
dinámicamente. No podemos usar una función de flecha aquí.Tratar con múltiples
this
valores también puede ser confuso, porque es difícil saber de quéthis
estaba hablando un autor:¿El autor realmente tenía la intención de llamar
Book.prototype.reformat
? ¿O se olvidó de atarthis
y tenía la intención de llamarReader.prototype.reformat
? Si cambiamos el controlador a una función de flecha, nos preguntaremos de manera similar si el autor quería la dinámicathis
, pero elegimos una flecha porque cabe en una línea:Uno puede plantearse: "¿Es excepcional que las flechas a veces sean una función incorrecta? Tal vez si raramente necesitamos
this
valores dinámicos , entonces estaría bien usar flechas la mayor parte del tiempo".Pero pregúntese esto: "¿Valdría la pena 'depurar el código y descubrir que el resultado de un error fue provocado por un' caso límite '?" Preferiría evitar problemas no solo la mayor parte del tiempo, sino 100% del tiempo
Hay una mejor manera: usar siempre
function
(porthis
lo que siempre se puede vincular dinámicamente) y siempre hacer referencia athis
través de una variable. Las variables son léxicas y asumen muchos nombres. Asignarthis
a una variable aclarará sus intenciones:Además, siempre asignar
this
a una variable (incluso cuando hay una solathis
o ninguna otra función) asegura que las intenciones de uno permanezcan claras incluso después de cambiar el código.Además, la dinámica
this
no es excepcional. jQuery se usa en más de 50 millones de sitios web (a partir de este escrito en febrero de 2016). Aquí hay otras API que se vinculanthis
dinámicamente:this
.this
.this
.EventTarget
conthis
.this
.(Estadísticas a través de http://trends.builtwith.com/javascript/jQuery y https://www.npmjs.com ).
Es probable que ya requiera
this
enlaces dinámicos .A
this
veces se espera un léxico , pero a veces no; así como athis
veces se espera una dinámica , pero a veces no. Afortunadamente, hay una mejor manera, que siempre produce y comunica el enlace esperado.En cuanto a la sintaxis concisa
Las funciones de flecha lograron proporcionar una "forma sintáctica más corta" para las funciones. ¿Pero estas funciones más cortas te harán más exitoso?
¿Es
x => x * x
"más fácil de leer" quefunction (x) { return x * x; }
? Tal vez lo sea, porque es más probable que produzca una única línea de código corta. De acuerdo con la influencia de Dyson de la velocidad de lectura y la longitud de la línea en la efectividad de la lectura desde la pantalla ,Se hacen justificaciones similares para el operador condicional (ternario) y para
if
declaraciones de una sola línea .Sin embargo, ¿ realmente está escribiendo las funciones matemáticas simples anunciadas en la propuesta ? Mis dominios no son matemáticos, por lo que mis subrutinas rara vez son tan elegantes. Por el contrario, comúnmente veo que las funciones de flecha rompen el límite de una columna y se ajustan a otra línea debido al editor o la guía de estilo, que anula la "legibilidad" según la definición de Dyson.
Uno podría plantearse: "¿Qué tal si usamos la versión corta para funciones cortas, cuando sea posible?" Pero ahora una regla estilística contradice una restricción del lenguaje: "Trate de usar la notación de función más corta posible, teniendo en cuenta que a veces solo la notación más larga se unirá
this
como se esperaba". Tal combinación hace que las flechas sean particularmente propensas al mal uso.Existen numerosos problemas con la sintaxis de la función de flecha:
Ambas funciones son sintácticamente válidas. Pero
doSomethingElse(x);
no está en el cuerpo deb
, es solo una declaración de alto nivel mal sangrada.Al expandirse a la forma de bloque, ya no hay un implícito
return
, que uno podría olvidar restaurar. Pero la expresión solo puede haber tenido la intención de producir un efecto secundario, entonces, ¿quién sabe sireturn
será necesario un explícito en el futuro?Lo que se puede considerar como un parámetro de descanso se puede analizar como el operador de propagación:
La asignación se puede confundir con los argumentos predeterminados:
Los bloques parecen objetos:
¿Qué significa esto?
¿Pretendía el autor crear un no-op, o una función que devuelva un objeto vacío? (Con esto en mente, ¿deberíamos ubicarnos
{
después=>
? ¿Deberíamos restringirnos solo a la sintaxis de la expresión? Eso reduciría aún más la frecuencia de las flechas).=>
se parece<=
y>=
:Para invocar una expresión de función de flecha inmediatamente, se debe colocar
()
en el exterior, pero colocarlo()
en el interior es válido y podría ser intencional.Sin embargo, si uno escribe
(() => doSomething()());
con la intención de escribir una expresión de función invocada inmediatamente, simplemente no sucederá nada.Es difícil argumentar que las funciones de flecha son "más comprensibles" con todos los casos anteriores en mente. Uno podría aprender todas las reglas especiales requeridas para utilizar esta sintaxis. ¿Realmente vale la pena?
La sintaxis de
function
es excepcionalmente generalizada. Usarfunction
exclusivamente significa que el lenguaje mismo evita que uno escriba código confuso. Para escribir procedimientos que deberían entenderse sintácticamente en todos los casos, elijofunction
.Sobre una directriz
Solicita una directriz que debe ser "clara" y "coherente". El uso de las funciones de flecha eventualmente dará como resultado un código sintácticamente válido, lógicamente inválido, con ambas formas de función entrelazadas, de manera significativa y arbitraria. Por lo tanto, ofrezco lo siguiente:
Pauta para la notación de funciones en ES6:
function
.this
a una variable. No utilice() => {}
.fuente
self
lugar de un esto. Las trampas de la función de flecha indicadas también son todas válidas, y los mismos estándares que en otras declaraciones que pueden ir sin llaves definitivamente se aplican aquí también; de lo contrario, creo que con su argumento uno podría defender las funciones de flecha en todas partes.this
es el problema de Javascript. En lugar de estar implícitamente vinculado,this
debe pasarse como un argumento explícito.Las funciones de flecha se crearon para simplificar la función
scope
y resolver lathis
palabra clave haciéndola más simple. Utilizan la=>
sintaxis, que se parece a una flecha.Nota: No reemplaza las funciones existentes. Si reemplaza cada sintaxis de función con funciones de flecha, no funcionará en todos los casos.
Echemos un vistazo a la sintaxis ES5 existente. Si la
this
palabra clave estuviera dentro del método de un objeto (una función que pertenece a un objeto), ¿a qué se referiría?El fragmento anterior se referirá a un
object
e imprimirá el nombre"RajiniKanth"
. Exploremos el fragmento a continuación y veamos qué señala esto aquí.¿Y si la
this
palabra clave estuviera dentro demethod’s function
?Aquí esto se referiría a
window object
que se hainner function
caídoscope
. Porquethis
, siempre hace referencia al propietario de la función en la que se encuentra, para este caso, ya que ahora está fuera del alcance, la ventana / objeto global.Cuando está dentro del
object
método de un - elfunction
propietario del objeto es el objeto. Por lo tanto, la palabra clave this está vinculada al objeto. Sin embargo, cuando está dentro de una función, ya sea solo o dentro de otro método, siempre se referirá alwindow/global
objeto.Hay formas de resolver este problema en nosotros
ES5
mismos, analicemos eso antes de sumergirnos en las funciones de flecha ES6 sobre cómo resolverlo.Por lo general, crearía una variable fuera de la función interna del método. Ahora el
‘forEach’
método obtiene accesothis
y, por lo tanto, lasobject’s
propiedades y sus valores.usando
bind
para adjuntar lathis
palabra clave que se refiere al método almethod’s inner function
.Ahora con la
ES6
función de flecha, podemos tratar ellexical scoping
problema de una manera más simple.Arrow functions
son más como declaraciones de funciones, excepto que hacenbind
estoparent scope
. Si elarrow function is in top scope
,this
el argumento se referirá awindow/global scope
, mientras que una función de flecha dentro de una función regular tendrá su este argumento lo mismo que su función externa.Con
arrow
funcionesthis
está vinculado al cierrescope
en el momento de la creación y no se puede cambiar. El nuevo operador, vincular, llamar y aplicar no tiene ningún efecto sobre esto.En el ejemplo anterior, perdimos el control de esto. Podemos resolver el ejemplo anterior usando una referencia variable de
this
o usandobind
. Con ES6, se vuelve más fácil administrar elthis
como está vinculadolexical scoping
.Cuando no a las funciones de flecha
Dentro de un objeto literal.
Actor.getName
se define con una función de flecha, pero en la invocación alerta sin definir porquethis.name
esundefined
como queda el contextowindow
.Ocurre porque la función de flecha une el contexto léxico con el
window object
... es decir, el alcance externo. La ejecuciónthis.name
es equivalente awindow.name
, que no está definida.Prototipo de objeto
La misma regla se aplica al definir métodos en a
prototype object
. En lugar de usar una función de flecha para definir el método sayCatName, que trae un incorrectocontext window
:Invocando constructores
this
en una invocación de construcción es el objeto recién creado. Al ejecutar nuevo Fn (), el contexto de laconstructor Fn
es un objeto nuevo:this instanceof Fn === true
.this
se configura desde el contexto envolvente, es decir, el ámbito externo que hace que no se asigne al objeto recién creado.Devolución de llamada con contexto dinámico
La función de flecha vincula la
context
declaración estática en y no es posible hacerla dinámica. Adjuntar oyentes de eventos a elementos DOM es una tarea común en la programación del lado del cliente. Un evento activa la función del controlador con esto como elemento de destino.this
es una ventana en una función de flecha que se define en el contexto global. Cuando ocurre un evento de clic, el navegador intenta invocar la función del controlador con el contexto del botón, pero la función de flecha no cambia su contexto predefinido.this.innerHTML
es equivalentewindow.innerHTML
y no tiene sentido.Debe aplicar una expresión de función, que permite cambiar esto dependiendo del elemento de destino:
Cuando el usuario hace clic en el botón, esto en la función del controlador es el botón. Por lo tanto,
this.innerHTML = 'Clicked button'
modifica correctamente el texto del botón para reflejar el estado en el que se hizo clic.Referencias: https://dmitripavlutin.com/when-not-to-use-arrow-functions-in-javascript/
fuente
using bind to attach the this keyword that refers to the method to the method’s inner function.
tiene errores de sintaxis.var Actor = { name: 'RajiniKanth', movies: ['Kabali', 'Sivaji', 'Baba'], showMovies: function() { this.movies.forEach(function(movie){ alert(this.name + ' has acted in ' + movie); }.bind(this)) } }; Actor.showMovies();
Uso: Todas las funciones de ES5 deben reemplazarse con las funciones de flecha de ES6, excepto en los siguientes escenarios:
Las funciones de flecha NO deben usarse:
this
/arguments
en una funciónthis
/arguments
por sí mismas, dependen de su contexto externo.constructor
this
.this
(que debería ser el objeto mismo).Comprendamos algunas de las variantes de las funciones de flecha para comprender mejor:
Variante 1 : cuando queremos pasar más de un argumento a una función y devolverle algún valor.
Versión ES5 :
Versión ES6 :
Nota: la
function
palabra clave NO es necesaria.=>
es requerido.{}
son opcionales, cuando no proporcionamos{}
return
está implícitamente agregado por JavaScript y cuando lo hacemos{}
necesitamos agregarloreturn
si lo necesitamos.Variante 2 : cuando queremos pasar SOLO un argumento a una función y devolverle algún valor.
Versión ES5 :
Versión ES6 :
Nota: Al pasar un solo argumento podemos omitir paréntesis
()
.Variante 3 : cuando NO queremos pasar ningún argumento a una función y NO queremos devolver ningún valor.
Versión ES5 :
Versión ES6 :
Variante 4 : cuando queremos regresar explícitamente de las funciones de flecha.
Versión ES6 :
Variante 5 : cuando queremos devolver un objeto de las funciones de flecha.
Versión ES6 :
Nota: Necesitamos envolver el objeto entre paréntesis, de lo
()
contrario, JavaScript no puede diferenciar entre un bloque y un objeto.Variante 6 : Las funciones de flecha NO tienen
arguments
(un objeto similar a una matriz) propio, dependen del contexto externoarguments
.Versión ES6 :
Nota:
foo
es una función ES5, con unaarguments
gran variedad de objetos y como un argumento pasado a ella es2
por lo quearguments[0]
para elfoo
es 2.abc
es una función ES6 flecha, ya que no tiene su propioarguments
por lo tanto, se imprimearguments[0]
defoo
su contexto externo en su lugar.Variante 7 : las funciones de flecha NO tienen
this
sus propias características, dependen del contexto externo parathis
Versión ES5 :
Nota: La devolución de llamada pasada a setTimeout es una función ES5 y tiene su propia función
this
que no está definida en eluse-strict
entorno, por lo tanto, obtenemos resultados:Versión ES6 :
Nota: La devolución de llamada se pasa a
setTimeout
una función ES6 flecha y que no tiene su propiothis
así que lo toma de su contexto exterior que esgreetUser
la que tienethis
que esobj6
de ahí obtenemos la salida:Varios: No podemos usar
new
con funciones de flecha. Las funciones de flecha no tienenprototype
propiedad. NO tenemos enlace dethis
cuando la función de flecha se invoca a través deapply
ocall
.fuente
Además de las excelentes respuestas hasta ahora, me gustaría presentar una razón muy diferente por la cual las funciones de flecha son, en cierto sentido, fundamentalmente mejores que las funciones de JavaScript "ordinarias". En aras de la discusión, supongamos temporalmente que usamos un corrector de tipo como TypeScript o "Flow" de Facebook. Considere el siguiente módulo de juguete, que es un código ECMAScript 6 válido más anotaciones de tipo Flow: (incluiré el código sin tipo, que sería el resultado real de Babel, al final de esta respuesta, para que realmente se pueda ejecutar).
Ahora vea qué sucede cuando usamos la clase C de un módulo diferente, como este:
Como puede ver, el verificador de tipos falló aquí: se suponía que f2 devolvería un número, ¡pero devolvió una cadena!
Peor aún, parece que ningún verificador de tipos concebible puede manejar funciones JavaScript normales (que no sean flechas), porque el "esto" de f2 no aparece en la lista de argumentos de f2, por lo que el tipo requerido para "esto" no podría agregarse. como una anotación a f2.
¿Este problema también afecta a las personas que no usan verificadores de tipo? Creo que sí, porque incluso cuando no tenemos tipos estáticos, pensamos como si estuvieran allí. ("Los primeros parámetros deben ser un número, el segundo una cadena", etc.) Un argumento oculto "este" que puede o no usarse en el cuerpo de la función hace que nuestra contabilidad mental sea más difícil.
Aquí está la versión sin tipo ejecutable, que sería producida por Babel:
fuente
Todavía mantengo todo lo que escribí en mi primera respuesta en este hilo. Sin embargo, mi opinión sobre el estilo de código se ha desarrollado desde entonces, por lo que tengo una nueva respuesta a esta pregunta que se basa en la última.
En cuanto a léxico
this
En mi última respuesta, evité deliberadamente una creencia subyacente que sostenía sobre este lenguaje, ya que no estaba directamente relacionado con el argumento que estaba haciendo. Sin embargo, sin que esto se indique explícitamente, puedo entender por qué muchas personas simplemente se oponen a mi recomendación de no usar flechas, cuando las encuentran tan útiles.
Mi creencia es esta: no deberíamos estar usando
this
en primer lugar. Por lo tanto, si una persona deliberadamente evita usarthis
en su código, entonces el "léxicothis
" de las flechas tiene poco o ningún valor. Además, bajo la premisa de quethis
es algo malo, el tratamiento de Arrow dethis
es menos que "algo bueno"; en cambio, es más una forma de control de daños para otra característica de lenguaje incorrecto.Me imagino que esto no se le ocurre a algunas personas, pero incluso a aquellos a quienes les ocurre, siempre deben encontrarse trabajando dentro de bases de código donde
this
aparece cientos de veces por archivo, y un poco (o mucho) control de daños es todo una persona razonable podría esperar. Entonces, las flechas pueden ser buenas, en cierto modo, cuando mejoran una mala situación.Incluso si es más fácil escribir código con
this
flechas que sin ellas, las reglas para usar flechas siguen siendo muy complejas (ver: hilo actual). Por lo tanto, las pautas no son "claras" ni "consistentes", como lo solicitó. Incluso si los programadores conocen las ambigüedades de las flechas, creo que se encogen de hombros y las aceptan de todos modos, porque el valor del léxico lasthis
eclipsa.Todo esto es un prefacio a la siguiente realización: si uno no usa
this
, entonces la ambigüedad acerca de lasthis
flechas normalmente se vuelve irrelevante. Las flechas se vuelven más neutrales en este contexto.En cuanto a la sintaxis concisa
Cuando escribí mi primera respuesta, era de la opinión de que incluso una adhesión servil a las mejores prácticas era un precio que valía la pena pagar si significaba que podía producir un código más perfecto. Pero finalmente me di cuenta de que la brevedad puede servir como una forma de abstracción que también puede mejorar la calidad del código, lo suficiente como para justificar el alejamiento de las mejores prácticas a veces.
En otras palabras: maldita sea, ¡también quiero funciones de una línea!
Sobre una directriz
Con la posibilidad de que
this
las funciones de flecha neutral y la brevedad valgan la pena, ofrezco la siguiente guía más indulgente:Pauta para la notación de funciones en ES6:
this
.fuente
Prefiero usar funciones de flecha en todo momento donde
this
no se necesita acceso a local , porque la función de flecha no vincula sus propios argumentos, super o new.target .fuente
De una manera simple,
Otra instancia:
Respuesta: La consola imprimiría 20.
La razón es que cada vez que se ejecuta una función se crea su propia pila, en este ejemplo, la
ex
función se ejecuta con elnew
operador para que se cree un contexto, y cuandoinner
se ejecuta, JS crearía una nueva pila y ejecutaría lainner
funciónglobal context
aunque haya un contexto localEntonces, si queremos
inner
función tenga un contexto local que seaex
entonces debemos vincular el contexto a la función interna.Las flechas resuelven este problema, en lugar de tomar el
Global context
, toman ellocal context
si existe. En elgiven example,
tomaránew ex()
comothis
.Entonces, en todos los casos donde el enlace es explícito, las flechas resuelven el problema por defecto.
fuente
Las funciones de flecha o Lambdas, se introdujeron en ES 6. Además de su elegancia en sintaxis mínima, la diferencia funcional más notable es el alcance
this
dentro de una función de flechaLimitaciones Funciones de flecha como métodos en un objeto
En el caso de
objA.print()
cuando elprint()
método se define usando regularfunction
, funcionó resolviendothis
adecuadamente laobjA
invocación del método, pero falló cuando se definió como una=>
función de flecha . Es porquethis
en una función regular cuando se invoca como método en un objeto (objA
), es el objeto mismo. Sin embargo, en el caso de una función de flecha,this
se une léxicamente a la delthis
alcance adjunto donde se definió (global / Ventana en nuestro caso) y permanece igual durante su invocación como método activadoobjA
.Ventajas de las funciones de una flecha sobre las funciones regulares en los métodos de un objeto PERO solo cuando
this
se espera que esté fijo y vinculado en la definición de tiempo.En el caso de
objB.print()
que elprint()
método se defina como una función que invocaconsole.log(
[$ {this.id} -> {this.name}] de)
forma asíncrona como una devolución de llamada activadasetTimeout
,this
resuelta correctamenteobjB
cuando una función de flecha se utilizó como devolución de llamada pero falló cuando la devolución de llamada se definió como una función regular. Es porque la=>
función de flecha pasó asetTimeout(()=>..)
cerrada sobrethis
léxicamente desde su padre, es decir. invocación de loobjB.print()
que lo definió. En otras palabras, la=>
función de flecha pasó asetTimeout(()==>...
atadaobjB
comothis
porque la invocación deobjB.print()
this
eraobjB
en sí.Podríamos usar fácilmente
Function.prototype.bind()
para hacer que la devolución de llamada definida como una función regular funcione, vinculándola a la correctathis
.Sin embargo, las funciones de flecha son útiles y menos propensas a errores en el caso de las devoluciones de llamada asíncronas, donde sabemos
this
en el momento de la definición de las funciones a las que llega y debe vincularse.Limitación de las funciones de flecha donde esto necesita cambiar a través de invocaciones
En cualquier momento, necesitamos una función cuyo
this
se pueda cambiar en el momento de la invocación, no podemos usar funciones de flecha.Ninguno de los anteriores funcionará con la función de flecha
const print = () => { console.log(
[$ {this.id} -> {this.name}]);}
yathis
que no se puede cambiar y permanecerá vinculado a la funciónthis
alcance del área adjunta donde se definió (global / Ventana). En todos estos ejemplos, invocamos la misma función con diferentes objetos (obj1
yobj2
) uno tras otro, los cuales fueron creados después de que laprint()
función fue declarada.Estos fueron ejemplos artificiales, pero pensemos en algunos ejemplos más de la vida real. Si tuviéramos que escribir nuestro
reduce()
método similar a uno que funcionearrays
, nuevamente no podemos definirlo como lambda, porque necesita inferirthis
del contexto de invocación, es decir. la matriz en la que se invocóPor esta razón,
constructor
funciones nunca se pueden definir como funciones de flecha, ya quethis
para una función constructora no se puede establecer en el momento de su declaración. Cada vez que se invoca una función constructora con unanew
palabra clave, se crea un nuevo objeto que luego se vincula a esa invocación particular.Además, cuando los marcos o sistemas aceptan una función o funciones de devolución de llamada que se invocarán más tarde con un contexto dinámico
this
, no podemos usar las funciones de flecha como de nuevothis
posible que tenga que cambiar con cada invocación. Esta situación comúnmente llega con los controladores de eventos DOMEsta es también la razón por la cual en frameworks como Angular 2+ y Vue.js esperan que los métodos de enlace de componentes de plantilla sean funciones / métodos regulares, ya
this
que su invocación es administrada por los marcos para las funciones de enlace. (Angular usa Zone.js para administrar el contexto asíncrono para invocaciones de funciones de enlace de plantilla de vista).Por otro lado, en React , cuando queremos pasar el método de un componente como un controlador de eventos, por ejemplo
<input onChange={this.handleOnchange} />
, debemos definirhandleOnchanage = (event)=> {this.props.onInputChange(event.target.value);}
como una función de flecha para cada invocación, queremos que sea la misma instancia del componente que produjo el JSX para renderizado Elemento DOM.Este artículo también está disponible en mi publicación Medium . Si le gusta el artile, o tiene algún comentario y sugerencia, aplauda o deje comentarios en Medium .
fuente