Kiedy należy używać argumentu „return” w funkcjach strzałek es6?

Odpowiedzi:

262

Jackson częściowo odpowiedział na to pytanie w podobnym pytaniu:

Niejawny zwrot, ale tylko wtedy, gdy nie ma bloku.

  • Spowoduje to błędy, gdy jednowierszowy rozwinie się do wielu wierszy, a programista zapomni dodać return.
  • Niejawny zwrot jest niejednoznaczny składniowo. (name) => {id: name}zwraca obiekt {id: name}... prawda? Źle. Wraca undefined. Te nawiasy klamrowe są jawnym blokiem. id:to etykieta.

Dodałbym do tego definicję bloku :

Instrukcja blokowa (lub instrukcja złożona w innych językach) służy do grupowania zera lub większej liczby instrukcji. Blok jest ograniczony parą nawiasów klamrowych.

Przykłady :

// returns: undefined
// explanation: an empty block with an implicit return
((name) => {})() 

// returns: 'Hi Jess'
// explanation: no block means implicit return
((name) => 'Hi ' + name)('Jess')

// returns: undefined
// explanation: explicit return required inside block, but is missing.
((name) => {'Hi ' + name})('Jess')

// returns: 'Hi Jess'
// explanation: explicit return in block exists
((name) => {return 'Hi ' + name})('Jess') 

// returns: undefined
// explanation: a block containing a single label. No explicit return.
// more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label
((name) => {id: name})('Jess') 

// returns: {id: 'Jess'}
// explanation: implicit return of expression ( ) which evaluates to an object
((name) => ({id: name}))('Jess') 

// returns: {id: 'Jess'}
// explanation: explicit return inside block returns object
((name) => {return {id: name}})('Jess') 
Jess Telford
źródło
Nie rozumiem tej składni… czy tworzysz klasę za pomocą klasy littoral, a następnie wywołujesz domyślny konstruktor z jednym argumentem („Jess”)? Pomyślałem, że to ((name) => ({id: 'Jess'}))
Michael Dausmann
3
@MichaelDausmann Jest to funkcja strzałkowa, która ma jeden parametr, namez funkcją zawartą w nawiasach i wywoływaną z jednym argumentem „Jess”. Kod między =>iw )('Jess')każdym przypadku jest treścią funkcji strzałki. Potraktuj to jak krótką formę natychmiastowo wywołanego wyrażenia funkcyjnego formularza(function (name) { return { id: name } })('Jess')
Russ Cam
Bardzo przydatne indded! pomaga wykryć problemy w Promises.all, które mapują elementy za pomocą funkcji strzałek i możesz zauważyć, jeśli otrzymasz tablicę undefined, jeśli żadna wartość nie została zwrócona do odwzorowania na tablicy za pomocą funkcji strzałkowych.
jay shah
Jaka byłaby wada uczynienia niejawnego powrotu systematycznego dla funkcji strzałkowych? Tak jak coffeescript ... (chociaż nie lubię coffeescript)
Augustin Riedinger
4
Dla jasności wydaje się, że ponieważ parser JS nie wie, czy oczekiwać wyrażenia (takiego jak wyrażenie zawierające literał obiektu {}) czy bloku , zakłada, że ​​a { }oznacza blok. Oznacza to, że gdy widzi id: name, że myśli, id:jest wyrazem tworząc etykietę (bardzo rzadko używanych funkcji JS, który zajmuje się kontrolą przepływu i używa :), a następnie nameponiżej id:jest po prostu oddzielne oświadczenie, że zawiera tylko zmienną name(& nic nie robi).
iono
18

Rozumiem tę praktyczną zasadę ...

W przypadku funkcji, które są efektywnie przekształcane (manipulacje jednowierszowymi argumentami), zwracanie jest niejawne.

Kandydaci to:

// square-root 
value => Math.sqrt(value)

// sum
(a,b) => a+b

W przypadku innych operacji (więcej niż jednoliniowe, które wymagają bloku, zwrot musi być jawny

Amarsh
źródło
11

Tutaj jest inny przypadek.

Pisząc komponent funkcjonalny w Reakcie, możesz użyć nawiasów do zawijania niejawnie zwróconego JSX.

const FunctionalComponent = () => (
  <div>
    <OtherComponent />
  </div>
);
Deci
źródło
4
Zawsze możesz użyć nawiasów, nie ma to związku z JSX ani React.
Emile Bergeron
4

Oto kolejny przypadek, który przysporzył mi kłopotów.

// the "tricky" way
const wrap = (foo) => (bar) => {
  if (foo === 'foo') return foo + ' ' + bar;
  return 'nofoo ' + bar;
}

Tutaj definiujemy funkcję zwracającą anonimową funkcję. „Podstępny” bit polega na tym, że ciało funkcji zewnętrznej funkcji (część rozpoczynająca się od (bar) => ...) wygląda wizualnie jak „blok”, ale tak nie jest. Ponieważ tak nie jest, włącza się niejawny zwrot.

Oto, jak by wykonać zawijanie:

// use wrap() to create a function withfoo()
const withfoo = wrap('foo');
// returns: foo bar
console.log(withfoo('bar'));

// use wrap() to create a function withoutfoo()
const withoutfoo = wrap('bar');
// returns: nofoo bar
console.log(withoutfoo('bar'));

Sposób, w jaki to rozpakowałem, aby upewnić się, że zrozumiałem, polegał na „usunięciu potwierdzenia” funkcji.

Oto semantyczny odpowiednik pierwszego bloku kodu, po prostu powodujący, że treść funkcji wrap () wykonuje jawny zwrot. Ta definicja daje takie same wyniki jak powyżej. Tutaj łączą się kropki. Porównaj pierwszy blok kodu powyżej z blokiem poniżej i jasne jest, że sama funkcja strzałki jest traktowana jako wyrażenie, a nie blok, i ma implikowany zwrot .

// the explicit return way
const wrap = (foo) => {
  return (bar) => {
    if (foo === 'foo') return foo + ' ' + bar;
    return 'nofoo ' + bar;
  }
}

W pełni niezarrowified wersja wrap byłaby taka, która choć nie jest tak zwarta jak wersja z grubą strzałką w górę, wydaje się dużo łatwiejsza do zrozumienia.

// the "no arrow functions" way
const wrap = function(foo) {
  return function(bar) {
    if (foo === 'foo') return foo + ' ' + bar;
    return 'nofoo ' + bar;
  };
};

W końcu, dla innych, którzy być może będą musieli przeczytać mój kod, i dla mnie w przyszłości, myślę, że wolałbym wybrać wersję bez strzałki, którą można zrozumieć wizualnie na pierwszy rzut oka, niż wersję ze strzałką, która zajmuje sporo czasu pomyślał (aw moim przypadku eksperymentował), aby narobić.

grayjohn
źródło
3

Funkcje strzałkowe pozwalają na niejawny zwrot: wartości są zwracane bez konieczności używania returnsłowa kluczowego.

Działa, gdy w treści funkcji znajduje się instrukcja on-line:

const myFunction = () => 'test'

console.log(myFunction()) //'test'

Inny przykład, zwracanie obiektu (pamiętaj, aby zawijać nawiasy klamrowe w nawiasy, aby uniknąć uznania go za nawiasy funkcji zawijania):

const myFunction = () => ({value: 'test'})

console.log(myFunction()) //{value: 'test'}

Flavio Copes
źródło
1
To powinna być prawidłowa odpowiedź, choć wymaga nieco więcej wyjaśnień. Zasadniczo, gdy treść funkcji jest wyrażeniem, a nie blokiem, wartość tego wyrażenia jest zwracana niejawnie. Popraw mnie, jeśli się mylę.
Paul-Sebastian Manole