Die neuen es6-Pfeilfunktionen sagen, dass sie return
unter bestimmten Umständen implizit sind:
Der Ausdruck ist auch der implizite Rückgabewert dieser Funktion.
In welchen Fällen muss ich es return
mit es6-Pfeilfunktionen verwenden?
Die neuen es6-Pfeilfunktionen sagen, dass sie return
unter bestimmten Umständen implizit sind:
Der Ausdruck ist auch der implizite Rückgabewert dieser Funktion.
In welchen Fällen muss ich es return
mit es6-Pfeilfunktionen verwenden?
Antworten:
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ückundefined
. 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')
name
wobei 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')
{}
) 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 name
Folgende id:
ist einfach eine separate Anweisung, die nur die Variable enthält name
(& tut nichts).
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
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>
);
Pfeilfunktionen ermöglichen eine implizite Rückgabe: Werte werden zurückgegeben, ohne dass das return
Schlü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'}
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.