Perché usare `const foo = () => {}` invece di `function foo () {}`


12

Ad esempio, in questo video Redux , l'istruttore usa sempre la sintassi come

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

dove vorrei solo usare il "tradizionale"

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

Che in realtà è più breve e, IMO, più chiaro. È più facile scansionare il bordo sinistro della pagina in modo abbastanza uniforme e strutturato per la parola "funzione" piuttosto che scansionare il bordo irregolare destro per un piccolo "=>".

Oltre a this, e cercando di essere oggettivo, non di opinione, c'è qualche utile differenza o vantaggio nella nuova sintassi?


3
Questa domanda su StackOverflow potrebbe interessarti: stackoverflow.com/questions/34361379/…
Vincent Savard

3
Non sono un esperto JavaScript, ma suppongo che constaiuta a garantire che la funzione non venga ridefinita in seguito.
MetaFight

Grazie @VincentSavard, è perfetto, e sostanzialmente quello che mi aspettavo: oltre a "questo", e roba prototipo / classe, non sembra esserci alcuna differenza reale.
user949300,

3
@ user949300 V'è una differenza, quella MetaFight menziona. Inoltre, prototype / "this stuff" diventa rapidamente distinzioni critiche.
msanford,

1
Per farla breve: dovresti valutare in modo chiaro e conciso un vantaggio marginale.
Wayne Bloss,

Risposte:


11

Le istruzioni di funzione (funzioni denominate, seconda sintassi mostrata) sono sollevate in cima all'intero ambito lessicale, anche quelle dietro blocchi arbitrari e di controllo, come le ifistruzioni. L'uso di const(like let) per dichiarare una variabile gli dà l'ambito del blocco, interrompe il sollevamento completo (sollevamento al mero blocco) e garantisce che non possa essere nuovamente dichiarato.

Quando si concatenano gli script insieme o alcuni utilizzano altri strumenti di creazione di pacchetti, il sollevamento delle funzioni può interrompere gli script in conflitto in modi difficili da eseguire il debug poiché non riesce in modo silenzioso. Una nuova dichiarazione constgenererà un'eccezione prima che il programma possa essere eseguito, quindi è molto più facile eseguire il debug.


Grazie. buona risposta. Ho lavorato principalmente su progetti JS più piccoli, o progetti server node.js in cui hanno un buon sistema di moduli per lo spazio dei nomi. Ma solo iniziare un progetto più lato client usando i bundler e questa è una buona idea.
user949300,

2
Solo una nota che eslint no-func-assegn può rilevare questo problema di redeclaration.
user949300,

2
Scrivere codice con segnali confusi per ottenere i vantaggi di un linguaggio tipicamente statico è un motivo per usare Typescript, non const. È un po 'miope, IMO, iniziare a usare constovunque per questo motivo nell'era di eslint, webpack, babel e così via. Nessuno sta concatenando più manualmente i file da almeno un decennio.
Wayne Bloss,

2

Ecco perché dovresti usare function:

  1. La segnalazione è chiara e concisa. Questo è di gran lunga più vantaggioso rispetto a qualsiasi delle preoccupazioni di sollevamento del caso limite elencate nell'altra risposta.

  2. In realtà si desidera il sollevamento all'interno dei moduli perché, come si può vedere dal codice seguente, la constdichiarazione di tryDoTheThingerrore fallisce silenziosamente e non verrà catturata fino a quando non si tenta di chiamarla.

  3. La maggior parte dei giovani con cui vengo in contatto inizia consta dichiarare ogni funzione perché è una mania in questo momento, come usare gli spazi sopra le schede o rendere tutto functional!!!perché "OOP cattivo". Non farlo. Non vuoi essere quel ragazzo che segue le mode senza comprendere appieno le implicazioni.

via 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]))
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.