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 thisdebe 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
newy no se puede usar al crearprototype - Fijo
thisvinculado 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
thisvariable 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 initialisationcomo una limitación?thises algo que puede hacer con funciones regulares pero no con funciones de flecha.Fixed this bound to scope at initialisationsea 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á:functionen el ámbito global y paraObject.prototypepropiedades.classpara constructores de objetos.=>cualquier otro lugar.¿Por qué usar las funciones de flecha en casi todas partes?
thisObjectque 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.functionsobresale inmediatamente para definir el alcance. Un desarrollador siempre puede buscar la siguientefunctiondeclaración más alta para ver cuálthisObjectes.¿Por qué usar siempre funciones regulares en el alcance global o alcance del módulo?
thisObject.windowobjeto (alcance global) se aborda mejor explícitamente.Object.prototypedefiniciones viven en el ámbito global (pensar,String.prototype.truncateetc.) y, en general, esas tienen que ser del tipofunction. El uso constantefunctionen 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
classcomo 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.mapy 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á unPromiseobjeto, 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
functionpalabra 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 lafunctionpalabra clave para cualquier cosa que realmente debería ser un método de clase o una clase.Notas
extendpalabra clave. Una diferencia menor es que las declaraciones de clase son constantes, mientras que las declaraciones de funciones no lo son.fuente
functiones cuando no quieresthisestar atado, ¿verdad? Mi escenario más común para esto son los eventos, donde es posible que deseethishacer 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ónthisléxica y ofreciendo una sintaxis concisa.Sin embargo,
thislé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
functionexclusivamente.En cuanto a léxico
thisthises problemático:Las funciones de flecha intentan solucionar el problema donde necesitamos acceder a una propiedad
thisdentro de una devolución de llamada. Ya hay varias formas de hacerlo: se podría asignarthisa una variable, usarbindo usar el tercer argumento disponible en losArraymé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
thisespecialmente. Ahora, hay dosthisvalores con los que lidiar:Debemos usar
functionparaeachunirthisdinámicamente. No podemos usar una función de flecha aquí.Tratar con múltiples
thisvalores también puede ser confuso, porque es difícil saber de quéthisestaba hablando un autor:¿El autor realmente tenía la intención de llamar
Book.prototype.reformat? ¿O se olvidó de atarthisy 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
thisvalores 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(porthislo que siempre se puede vincular dinámicamente) y siempre hacer referencia athistravés de una variable. Las variables son léxicas y asumen muchos nombres. Asignarthisa una variable aclarará sus intenciones:Además, siempre asignar
thisa una variable (incluso cuando hay una solathiso 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
thisno 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 vinculanthisdinámicamente:this.this.this.EventTargetconthis.this.(Estadísticas a través de http://trends.builtwith.com/javascript/jQuery y https://www.npmjs.com ).
Es probable que ya requiera
thisenlaces dinámicos .A
thisveces se espera un léxico , pero a veces no; así como athisveces 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
ifdeclaraciones 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á
thiscomo 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 sireturnserá 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
functiones excepcionalmente generalizada. Usarfunctionexclusivamente 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.thisa una variable. No utilice() => {}.fuente
selflugar 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.thises el problema de Javascript. En lugar de estar implícitamente vinculado,thisdebe pasarse como un argumento explícito.Las funciones de flecha se crearon para simplificar la función
scopey resolver lathispalabra 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
thispalabra 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
objecte imprimirá el nombre"RajiniKanth". Exploremos el fragmento a continuación y veamos qué señala esto aquí.¿Y si la
thispalabra clave estuviera dentro demethod’s function?Aquí esto se referiría a
window objectque se hainner functioncaí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
objectmétodo de un - elfunctionpropietario 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/globalobjeto.Hay formas de resolver este problema en nosotros
ES5mismos, 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 accesothisy, por lo tanto, lasobject’spropiedades y sus valores.usando
bindpara adjuntar lathispalabra clave que se refiere al método almethod’s inner function.Ahora con la
ES6función de flecha, podemos tratar ellexical scopingproblema de una manera más simple.Arrow functionsson más como declaraciones de funciones, excepto que hacenbindestoparent scope. Si elarrow function is in top scope,thisel 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
arrowfuncionesthisestá vinculado al cierrescopeen 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
thiso usandobind. Con ES6, se vuelve más fácil administrar elthiscomo está vinculadolexical scoping.Cuando no a las funciones de flecha
Dentro de un objeto literal.
Actor.getNamese define con una función de flecha, pero en la invocación alerta sin definir porquethis.nameesundefinedcomo 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.namees 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
thisen una invocación de construcción es el objeto recién creado. Al ejecutar nuevo Fn (), el contexto de laconstructor Fnes un objeto nuevo:this instanceof Fn === true.thisse 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
contextdeclaració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.thises 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.innerHTMLes equivalentewindow.innerHTMLy 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/argumentsen una funciónthis/argumentspor sí mismas, dependen de su contexto externo.constructorthis.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
functionpalabra clave NO es necesaria.=>es requerido.{}son opcionales, cuando no proporcionamos{}returnestá implícitamente agregado por JavaScript y cuando lo hacemos{}necesitamos agregarloreturnsi 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:
fooes una función ES5, con unaargumentsgran variedad de objetos y como un argumento pasado a ella es2por lo quearguments[0]para elfooes 2.abces una función ES6 flecha, ya que no tiene su propioargumentspor lo tanto, se imprimearguments[0]defoosu contexto externo en su lugar.Variante 7 : las funciones de flecha NO tienen
thissus propias características, dependen del contexto externo parathisVersión ES5 :
Nota: La devolución de llamada pasada a setTimeout es una función ES5 y tiene su propia función
thisque no está definida en eluse-strictentorno, por lo tanto, obtenemos resultados:Versión ES6 :
Nota: La devolución de llamada se pasa a
setTimeoutuna función ES6 flecha y que no tiene su propiothisasí que lo toma de su contexto exterior que esgreetUserla que tienethisque esobj6de ahí obtenemos la salida:Varios: No podemos usar
newcon funciones de flecha. Las funciones de flecha no tienenprototypepropiedad. NO tenemos enlace dethiscuando la función de flecha se invoca a través deapplyocall.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
thisEn 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
thisen primer lugar. Por lo tanto, si una persona deliberadamente evita usarthisen su código, entonces el "léxicothis" de las flechas tiene poco o ningún valor. Además, bajo la premisa de quethises algo malo, el tratamiento de Arrow dethises 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
thisaparece 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
thisflechas 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 lasthiseclipsa.Todo esto es un prefacio a la siguiente realización: si uno no usa
this, entonces la ambigüedad acerca de lasthisflechas 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
thislas 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
thisno 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
exfunción se ejecuta con elnewoperador para que se cree un contexto, y cuandoinnerse ejecuta, JS crearía una nueva pila y ejecutaría lainnerfunciónglobal contextaunque haya un contexto localEntonces, si queremos
innerfunción tenga un contexto local que seaexentonces debemos vincular el contexto a la función interna.Las flechas resuelven este problema, en lugar de tomar el
Global context, toman ellocal contextsi 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
thisdentro 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ó resolviendothisadecuadamente laobjAinvocación del método, pero falló cuando se definió como una=>función de flecha . Es porquethisen 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,thisse une léxicamente a la delthisalcance 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
thisse 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,thisresuelta correctamenteobjBcuando 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 sobrethisléxicamente desde su padre, es decir. invocación de loobjB.print()que lo definió. En otras palabras, la=>función de flecha pasó asetTimeout(()==>...atadaobjBcomothisporque la invocación deobjB.print()thiseraobjBen 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
thisen 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
thisse 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}]);}yathisque no se puede cambiar y permanecerá vinculado a la funciónthisalcance del área adjunta donde se definió (global / Ventana). En todos estos ejemplos, invocamos la misma función con diferentes objetos (obj1yobj2) 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 inferirthisdel contexto de invocación, es decir. la matriz en la que se invocóPor esta razón,
constructorfunciones nunca se pueden definir como funciones de flecha, ya quethispara 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 unanewpalabra 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 nuevothisposible 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
thisque 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