Wann sollte ich "return" in es6-Pfeilfunktionen verwenden?

Antworten:

261

Jackson hat dies teilweise in einer ähnlichen Frage beantwortet :

Implizite Rückgabe, aber nur, wenn kein Block vorhanden ist.

  • Dies führt zu Fehlern, wenn ein Einzeiler auf mehrere Zeilen erweitert wird und der Programmierer vergisst, a hinzuzufügen return.
  • Die implizite Rückgabe ist syntaktisch nicht eindeutig. (name) => {id: name}gibt das Objekt zurück {id: name}... richtig? Falsch. Es kehrt zurück undefined. Diese Klammern sind ein expliziter Block. id:ist ein Etikett.

Ich würde dem die Definition eines Blocks hinzufügen :

Eine Blockanweisung (oder eine zusammengesetzte Anweisung in anderen Sprachen) wird verwendet, um null oder mehr Anweisungen zu gruppieren. Der Block wird durch ein Paar geschweifter Klammern begrenzt.

Beispiele :

// 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
quelle
Ich verstehe diese Syntax nicht. Erstellen Sie eine Klasse mit einem Klassen-Litoral und rufen Sie dann einen impliziten Konstruktor mit einem Argument ('Jess') auf? Ich dachte du würdest dazu ((name) => ({id: 'Jess'}))
Michael Dausmann
3
@MichaelDausmann Es handelt sich um eine Pfeilfunktion mit einem Parameter, namewobei die Funktion in Klammern steht und mit einem Argument "Jess" aufgerufen wird. Der Code zwischen =>und ist )('Jess')jeweils der Hauptteil der Pfeilfunktion. Betrachten Sie es als eine Kurzform eines sofort aufgerufenen Funktionsausdrucks der Form(function (name) { return { id: name } })('Jess')
Russ Cam
Sehr nützlich indded! Hilft dabei, Probleme in Promises.all zu erkennen, die Elemente mit einer Pfeilfunktion zuordnen, und Sie können feststellen, ob Sie ein Array von undefined erhalten, wenn kein Wert für die Zuordnung über ein Array mit Pfeilfunktionen zurückgegeben wurde.
Jay Shah
Was wäre der Nachteil gewesen, wenn die implizite Rückgabe für Pfeilfunktionen systematisch gemacht worden wäre? Genau wie Coffeescript ... (obwohl ich Coffeescript nicht mag)
Augustin Riedinger
4
Es scheint klar zu sein, dass der JS-Parser, da er nicht weiß, ob er einen Ausdruck (z. B. einen Ausdruck, der ein Objektliteral enthält {}) oder einen Block erwartet , davon ausgeht, dass a { }einen Block bezeichnet. Das heißt, wenn es sieht id: name, denkt es, dass id:es ein Ausdruck ist, der eine Beschriftung erstellt (eine sehr selten verwendete Funktion von JS, die sich mit der Flusskontrolle befasst und a verwendet :), und das nameFolgende id:ist einfach eine separate Anweisung, die nur die Variable enthält name(& tut nichts).
Iono
17

Ich verstehe diese Faustregel ...

Für Funktionen, die effektiv transformiert werden (einzeilige Manipulationen von Argumenten), ist die Rückgabe implizit.

Kandidaten sind:

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

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

Für andere Vorgänge (mehr als Einzeiler, für die ein Block erforderlich ist, muss die Rückgabe explizit sein

Amarsh
quelle
11

Hier gibt es noch einen anderen Fall.

Wenn Sie eine Funktionskomponente in React schreiben, können Sie implizit zurückgegebenes JSX in Klammern setzen.

const FunctionalComponent = () => (
  <div>
    <OtherComponent />
  </div>
);
Deci
quelle
4
Sie können immer Klammern verwenden, die nichts mit JSX oder React zu tun haben.
Emile Bergeron
3

Pfeilfunktionen ermöglichen eine implizite Rückgabe: Werte werden zurückgegeben, ohne dass das returnSchlüsselwort verwendet werden muss.

Es funktioniert, wenn der Funktionskörper eine Online-Anweisung enthält:

const myFunction = () => 'test'

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

Ein weiteres Beispiel für die Rückgabe eines Objekts (denken Sie daran, die geschweiften Klammern in Klammern zu setzen, um zu vermeiden, dass es als Klammer der Umhüllungsfunktion betrachtet wird):

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

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

Flavio Copes
quelle
1
Dies sollte die richtige Antwort sein, obwohl sie etwas näher erläutert werden muss. Wenn der Funktionskörper ein Ausdruck und kein Block ist, wird der Wert dieses Ausdrucks implizit zurückgegeben. Korrigiere mich, wenn ich falsch liege.
Paul-Sebastian Manole
3

Hier ist ein weiterer Fall, der mir Probleme bereitete.

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

Hier definieren wir eine Funktion, die eine anonyme Funktion zurückgibt. Das "knifflige" Bit ist, dass der Funktionskörper für die äußere Funktion (der Teil, der mit (bar) => ... beginnt) visuell wie ein "Block" aussieht, aber nicht. Da dies nicht der Fall ist, setzt die implizite Rückkehr ein.

So würde Wrap ausgeführt:

// 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'));

Die Art und Weise, wie ich dies entpackt habe, um sicherzustellen, dass ich verstanden habe, war, die Funktionen zu "entarrowifizieren".

Hier ist das semantische Äquivalent des ersten Codeblocks, bei dem der Körper von wrap () einfach eine explizite Rückgabe ausführt. Diese Definition führt zu den gleichen Ergebnissen wie oben. Hier verbinden sich die Punkte. Vergleichen Sie den ersten Codeblock oben mit dem unten stehenden, und es ist klar, dass eine Pfeilfunktion selbst als Ausdruck und nicht als Block behandelt wird und die implizite Rückgabe aufweist .

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

Die vollständig nicht gezeichnete Version von Wrap wäre wie folgt, die zwar nicht so kompakt ist wie die Version mit den fetten Pfeilen, aber viel einfacher zu verstehen scheint.

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

Letztendlich denke ich, dass ich für andere, die meinen Code lesen müssen, und für mich in Zukunft lieber die Nicht-Pfeil-Version wählen würde, die auf den ersten Blick visuell verstanden werden kann, als die Pfeil-Version, die ein gutes Stück davon benötigt dachte (und in meinem Fall experimentieren) zu grok.

Grayjohn
quelle