Le nuove funzioni della freccia es6 dicono che return
è implicito in alcune circostanze:
L'espressione è anche il valore di ritorno implicito di quella funzione.
In quali casi devo utilizzare le return
funzioni freccia es6?
Le nuove funzioni della freccia es6 dicono che return
è implicito in alcune circostanze:
L'espressione è anche il valore di ritorno implicito di quella funzione.
In quali casi devo utilizzare le return
funzioni freccia es6?
Risposte:
Jackson ha parzialmente risposto a questa domanda in una domanda simile:
Ritorno implicito, ma solo se non è presente alcun blocco.
- Ciò comporterà errori quando una riga si espande su più righe e il programmatore dimentica di aggiungere un
return
.- Il ritorno implicito è sintatticamente ambiguo.
(name) => {id: name}
restituisce l'oggetto{id: name}
... giusto? Sbagliato. Ritornaundefined
. Quelle parentesi graffe sono un blocco esplicito.id:
è un'etichetta.
Aggiungerei a questo la definizione di un blocco :
Un'istruzione di blocco (o un'istruzione composta in altre lingue) viene utilizzata per raggruppare zero o più istruzioni. Il blocco è delimitato da una coppia di parentesi graffe.
Esempi :
// 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
con la funzione racchiusa tra parentesi e invocata con un argomento, "Jess". Il codice tra =>
e )('Jess')
in ogni caso è il corpo della funzione freccia. Consideralo come una breve forma di un'espressione di funzione immediatamente invocata del modulo(function (name) { return { id: name } })('Jess')
{}
) o un blocco , assume che un { }
denoti un blocco. Ciò significa che quando vede id: name
, pensa che id:
sia un'espressione che crea un'etichetta (una funzione molto insolita di JS che si occupa del controllo del flusso e usa a :
), e quindi la name
seguente id:
è semplicemente un'istruzione separata che contiene solo la variabile name
(& non fa nulla).
Capisco questa regola empirica ...
Per le funzioni che sono effettivamente trasformate (manipolazioni di una riga di argomenti), il ritorno è implicito.
I candidati sono:
// square-root
value => Math.sqrt(value)
// sum
(a,b) => a+b
Per altre operazioni (più di una riga che richiedono un blocco, il ritorno deve essere esplicito
C'è un altro caso qui.
Quando si scrive un componente funzionale in React, è possibile utilizzare le parentesi per avvolgere JSX implicitamente restituito.
const FunctionalComponent = () => (
<div>
<OtherComponent />
</div>
);
Ecco un altro caso che mi ha dato qualche problema.
// the "tricky" way
const wrap = (foo) => (bar) => {
if (foo === 'foo') return foo + ' ' + bar;
return 'nofoo ' + bar;
}
Qui definiamo una funzione che restituisce una funzione anonima. Il bit "difficile" è che il corpo della funzione per la funzione esterna (la parte che inizia con (bar) => ...) appare visivamente come un "blocco", ma non lo è. Dato che non lo è, entra in gioco il ritorno implicito.
Ecco come eseguire il wrapping:
// 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'));
Il modo in cui l'ho decompresso per essere sicuro di aver capito che era di "unificare" le funzioni.
Ecco l'equivalente semantico del primo blocco di codice, facendo semplicemente in modo che il corpo di wrap () faccia un ritorno esplicito. Questa definizione produce gli stessi risultati di cui sopra. Questo è dove i punti si collegano. Confronta il primo blocco di codice sopra con quello sotto, ed è chiaro che una funzione freccia stessa viene trattata come un'espressione, non un blocco, e ha il ritorno implicito .
// the explicit return way
const wrap = (foo) => {
return (bar) => {
if (foo === 'foo') return foo + ' ' + bar;
return 'nofoo ' + bar;
}
}
La versione completamente non ristretta di avvolgimento sarebbe così, che sebbene non sia compatta come la versione grassa con le frecce, sembra molto più facile da capire.
// the "no arrow functions" way
const wrap = function(foo) {
return function(bar) {
if (foo === 'foo') return foo + ' ' + bar;
return 'nofoo ' + bar;
};
};
Alla fine, per gli altri che potrebbero dover leggere il mio codice, e futuro me, penso che preferirei andare alla versione non freccia che può essere compresa visivamente a prima vista, piuttosto che quella freccia che prende un bel po 'di ho pensato (e nel mio caso sperimentazione) a grok.
Le funzioni freccia consentono di ottenere un ritorno implicito: i valori vengono restituiti senza dover utilizzare la return
parola chiave.
Funziona quando è presente un'istruzione online nel corpo della funzione:
const myFunction = () => 'test'
console.log(myFunction()) //'test'
Un altro esempio, restituendo un oggetto (ricordarsi di avvolgere le parentesi graffe tra parentesi per evitare che venga considerato le parentesi del corpo della funzione di avvolgimento):
const myFunction = () => ({value: 'test'})
console.log(myFunction()) //{value: 'test'}