Po co używać `const foo = () => {}` zamiast `function foo () {}`

12

Na przykład w tym filmie Redux instruktor zawsze używa składni podobnej do

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

gdzie po prostu użyłbym „tradycyjnego”

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

Co jest w rzeczywistości krótsze i, IMO, wyraźniejsze. Łatwiej jest zeskanować dość wyrównaną i uporządkowaną lewą krawędź strony pod kątem słowa „funkcja” niż zeskanować nierówną prawą krawędź pod kątem małego „=>”.

Czy prócz thisobiektywności, a nie opinii, jest jakaś użyteczna różnica lub przewaga w nowej składni?

użytkownik949300
źródło
3
To pytanie na StackOverflow może Cię zainteresować: stackoverflow.com/questions/34361379/...
Vincent Savard
3
Nie jestem ekspertem w dziedzinie JavaScript, ale domyślam się, constże funkcja nie zostanie później zdefiniowana ponownie.
MetaFight,
Dzięki @VincentSavard, to jest idealne i zasadniczo tego się spodziewałem: poza „tym” i prototypem / klasą rzeczy, wydaje się, że nie ma prawdziwej różnicy.
user949300,
3
@ user949300 Jest to różnica, jeden MetaFight wspomina. Również protype / „this stuff” szybko stają się krytycznymi wyróżnieniami.
msanford,
1
Krótko mówiąc: należy docenić jasne i zwięzłe korzyści wynikające z przewagi nad konkurencją.
Wayne Bloss,

Odpowiedzi:

11

Instrukcje funkcyjne (nazwane funkcje, pokazana druga składnia) są umieszczane na górze pełnego zakresu leksykalnego, nawet te za blokami arbitralnymi i kontrolnymi, takie jak ifinstrukcje. Użycie const(podobnego let) do zadeklarowania zmiennej daje zakres bloku, zatrzymuje pełne podnoszenie (podnoszenie do zwykłego bloku) i zapewnia, że ​​nie będzie można go ponownie zadeklarować.

Podczas łączenia skryptów razem lub korzystania z innych narzędzi do budowania pakietów, podnoszenie funkcji może uszkodzić skrypty będące w konflikcie w sposób trudny do debugowania, ponieważ kończy się niepowodzeniem. Ponownie zadeklarowane zgłoszenie constspowoduje wyjątek przed uruchomieniem programu, dzięki czemu debugowanie jest znacznie łatwiejsze.

dandavis
źródło
Dzięki. dobra odpowiedź. Pracowałem głównie nad mniejszymi projektami JS lub projektami serwerów node.js, w których mają dobry system modułów do przestrzeni nazw. Ale dopiero zaczynam od projektu po stronie klienta korzystającego z programów pakujących i jest to dobry wgląd.
user949300,
2
Tylko uwaga, że eslint no-func-przypisanie może wychwycić ten problem z deklaracją.
user949300
2
Pisanie kodu, który ma mylące sygnały w celu uzyskania korzyści płynących z używania języka o typie statycznym, jest powodem, dla którego nie należy używać maszynopisu const. IMO to trochę krótkowzroczność, aby zacząć używać constwszędzie z tego powodu w czasach eslint, webpack, babel i tak dalej. Od co najmniej dekady nikt już nie łączy ręcznie plików.
Wayne Bloss,
2

Oto dlaczego powinieneś użyć function:

  1. Sygnalizacja jest jasna i zwięzła. Jest to o wiele bardziej korzystne niż jakikolwiek problem związany z podnoszeniem krawędzi wymieniony w drugiej odpowiedzi.

  2. Naprawdę chcesz podnosić w modułach, ponieważ jak widać z poniższego kodu, constdeklaracja tryDoTheThingawarii po cichu i nie zostanie złapana, dopóki nie spróbujesz jej wywołać.

  3. Większość juniorów, z którymi się stykam, zaczyna constdeklarować każdą funkcję, ponieważ jest to teraz moda, jak używanie spacji nad tabulatorami lub robienie wszystkiego, functional!!!ponieważ „OOP źle”. Nie rób tego Nie chcesz być tym facetem, który podąża za modami bez pełnego zrozumienia implikacji.

przez 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
źródło