Pourquoi utiliser `const foo = () => {}` au lieu de `function foo () {}`

12

Par exemple, dans cette vidéo Redux , l'instructeur utilise toujours une syntaxe comme

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

où j'utiliserais simplement le "traditionnel"

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

Ce qui est en fait plus court et, à mon avis, plus clair. Il est plus facile de scanner le bord gauche assez uniforme et structuré de la page pour le mot «fonction» que de scanner le bord droit irrégulier pour un petit «=>».

À part this, et en essayant d'être objectif, pas d'opinion, y a-t-il une différence ou un avantage utile à la nouvelle syntaxe?

user949300
la source
3
Cette question sur StackOverflow peut vous intéresser: stackoverflow.com/questions/34361379/…
Vincent Savard
3
Je ne suis pas un expert en JavaScript, mais je suppose que cela constpermet de s'assurer que la fonction ne sera pas redéfinie plus tard.
MetaFight
Merci @VincentSavard, c'est parfait, et fondamentalement ce à quoi je m'attendais: à part "ceci" et les trucs prototype / classe, il ne semble pas y avoir de réelle différence.
user949300
3
@ user949300 Il y a une différence, celle que MetaFight mentionne. De plus, protype / "ce genre de choses" deviennent rapidement des distinctions critiques.
msanford du
1
Pour faire court: vous devez privilégier un avantage clair et concis par rapport à un avantage de pointe.
Wayne Bloss

Réponses:

11

Les instructions de fonction (fonctions nommées, 2e syntaxe illustrée) sont hissées au sommet de la portée lexicale complète, même celles qui se trouvent derrière des blocs arbitraires et de contrôle, comme les ifinstructions. L'utilisation de const(like let) pour déclarer une variable lui donne une portée de bloc, arrête le levage complet (levage vers un simple bloc) et garantit qu'elle ne peut pas être déclarée à nouveau.

Lors de la concaténation de scripts ensemble ou de l'utilisation d'autres outils de création de packages, le levage de fonctions peut casser des scripts conflictuels de manière difficile à déboguer car il échoue silencieusement. Une nouvelle déclaration constlèvera une exception avant que le programme puisse s'exécuter, il est donc beaucoup plus facile de déboguer.

dandavis
la source
Merci. bonne réponse. J'ai principalement travaillé sur des projets JS plus petits, ou des projets de serveur node.js où ils ont un bon système de modules pour l'espace de noms. Mais juste commencer un projet plus côté client en utilisant des bundlers et c'est une bonne idée.
user949300
2
Juste une note que eslint no-func-assign peut attraper ce problème de redéclaration.
user949300
2
L'écriture de code qui a des signaux déroutants afin d'obtenir les avantages d'un langage typé statiquement est une raison pour utiliser Typescript, non const. C'est un peu myope, OMI, de commencer à utiliser constpartout pour cette raison à l'ère de l'eslint, du webpack, du babel et ainsi de suite. Personne ne concatène les fichiers ensemble manuellement depuis au moins une décennie maintenant.
Wayne Bloss
2

Voici pourquoi vous devriez utiliser function:

  1. La signalisation est claire et concise. Ceci est beaucoup plus bénéfique que toutes les préoccupations de levage de cas de bord qui sont énumérées dans l'autre réponse.

  2. Vous voulez réellement hisser dans les modules car comme vous pouvez le voir dans le code ci-dessous, la constdéclaration d' tryDoTheThingéchec en silence et ne sera pas interceptée jusqu'à ce que vous essayiez de l'appeler.

  3. La plupart des juniors avec lesquels je suis en contact commencent à utiliser constpour déclarer chaque fonction parce que c'est une mode en ce moment, comme utiliser des espaces sur des tabulations ou tout faire functional!!!parce que "OOP mauvais". Ne fais pas ça. Vous ne voulez pas être ce gars qui suit les modes sans comprendre pleinement les implications.

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

contre

/*
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
la source