¿Por qué usar `const foo = () => {}` en lugar de `function foo () {}`

12

Por ejemplo, en este video de Redux , el instructor siempre usa sintaxis como

const counter = (state=0, action) => {
   ... function body here
}

donde simplemente usaría el "tradicional"

function counter(state=0, action) {
   ... function body here
}

Que en realidad es más corto y, en mi opinión, más claro. Es más fácil escanear el borde izquierdo bastante uniforme y estructurado de la página para la palabra "función" que escanear el borde derecho irregular para un pequeño "=>".

Aparte de this, y tratando de ser objetivo, no de opinión, ¿hay alguna diferencia útil o ventaja en la sintaxis novedosa?

user949300
fuente
3
Esta pregunta sobre StackOverflow puede interesarle: stackoverflow.com/questions/34361379/…
Vincent Savard
3
No soy un experto en JavaScript, pero supongo que constayuda a garantizar que la función no se redefina más adelante.
MetaFight
Gracias @VincentSavard, eso es perfecto, y básicamente lo que esperaba: Aparte de "esto", y prototipo / material de clase, parece que no hay una diferencia real.
user949300 el
3
@ user949300 No es una diferencia, el MetaFight menciona. Además, protype / "this stuff" también se convierte rápidamente en distinciones críticas.
msanford
1
En pocas palabras: debe valorar de manera clara y concisa el beneficio de un caso marginal.
Wayne Bloss

Respuestas:

11

Las declaraciones de función (funciones nombradas, se muestra la segunda sintaxis) se elevan a la parte superior del alcance léxico completo, incluso aquellos detrás de bloques arbitrarios y de control, como las ifdeclaraciones. El uso de const(like let) para declarar una variable le da un alcance de bloque, detiene la elevación completa (elevación a un mero bloque) y garantiza que no se pueda volver a declarar.

Cuando se concatenan scripts juntos, o algunos usan otras herramientas de creación de paquetes, el levantamiento de funciones puede romper scripts conflictivos de formas que son difíciles de depurar ya que falla en silencio. Una nueva declaración constarrojará una excepción antes de que el programa pueda ejecutarse, por lo que es mucho más fácil de depurar.

dandavis
fuente
Gracias. buena respuesta. Principalmente he trabajado en proyectos JS más pequeños o proyectos de servidor node.js donde tienen un buen sistema de módulos para el espacio de nombres. Pero solo comenzando en un proyecto más del lado del cliente usando paquetes y esto es una buena idea.
user949300
2
Solo una nota de que eslint no-func-assist puede detectar este problema de redeclaración.
user949300 el
2
Escribir un código que tenga señales confusas para obtener los beneficios de un lenguaje estáticamente tipado es una razón para usar Typecript, no const. Es un poco miope, en mi opinión, comenzar a usar en consttodas partes por esta razón en la era de eslint, webpack, babel, etc. Ya nadie está concatenando archivos manualmente durante al menos una década.
Wayne Bloss
2

He aquí por qué debería usar function:

  1. La señalización es clara y concisa. Esto es mucho más beneficioso que cualquiera de las inquietudes de elevación de casos extremos que se enumeran en la otra respuesta.

  2. En realidad, desea izar dentro de los módulos porque, como puede ver en el siguiente código, la constdeclaración de tryDoTheThingfalla en silencio y no se detectará hasta que intente llamarla.

  3. La mayoría de los juniors con los que entro en contacto comienzan a usar constpara declarar cada función porque es una moda en este momento, como usar espacios sobre pestañas o hacer todo functional!!!porque "OOP es malo". No hagas eso. No quieres ser ese tipo que sigue las modas sin comprender completamente las implicaciones.

a través de https://gist.github.com/stephenjfox/fec4c72c7f6ae254f31407295dc72074


/*
This shows that, because of block-scoping, const function references must be
invoked in-order or else things will fail silently.
const's are added the name space serially (in the order in which they appear)
and much of the body isn't declared when we first try to invoke or functions
*/


const tryDoTheThing = () => {
  console.log(`This is me trying to be awesome ${getAwesome()}`)
}


// "getAwesome is not defined", because it is referenced too early
tryDoTheThing() // comment to see the rest work


const getAwesome = () => (+((Math.random() * 10000).toString().split('.')[0]))


const doTheThing = () => {
  console.log(`This is awesome! ${getAwesome()}`)
}

doTheThing() // prints

vs

/*
Function declarations are given two passes, where the first lifts them to
the top of the namespace, allowing "out of order" usage
*/

doTheThing();


function doTheThing() {
  console.log(`This is awesome number ${getAwesome()}`)
}

function getAwesome() {
  return (+((Math.random() * 10000).toString().split('.')[0]))
}
Wayne Bloss
fuente