Las nuevas funciones de flecha es6 dicen que return
está implícita en algunas circunstancias:
La expresión también es el valor de retorno implícito de esa función.
¿En qué casos necesito usar return
con las funciones de flecha es6?
Las nuevas funciones de flecha es6 dicen que return
está implícita en algunas circunstancias:
La expresión también es el valor de retorno implícito de esa función.
¿En qué casos necesito usar return
con las funciones de flecha es6?
Respuestas:
Jackson ha respondido parcialmente esto en una pregunta similar:
Retorno implícito, pero solo si no hay bloque.
- Esto dará lugar a errores cuando una línea se expande a varias líneas y el programador olvida agregar un
return
.- El retorno implícito es sintácticamente ambiguo.
(name) => {id: name}
devuelve el objeto{id: name}
... ¿verdad? Incorrecto. Vuelveundefined
. Esas llaves son un bloque explícito.id:
Es una etiqueta.
Agregaría a esto la definición de un bloque :
Una declaración de bloque (o declaración compuesta en otros idiomas) se usa para agrupar cero o más declaraciones. El bloque está delimitado por un par de llaves.
Ejemplos :
// 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 función entre paréntesis e invocada con un argumento, "Jess". El código entre =>
y )('Jess')
en cada caso es el cuerpo de la función de flecha. Considérelo como una forma corta de una expresión de función invocada inmediatamente de la forma(function (name) { return { id: name } })('Jess')
{}
) o un bloque , supone que a { }
denota un bloque. Eso significa que cuando ve id: name
, piensa que id:
es una expresión que crea una etiqueta (una característica muy poco común de JS que se ocupa del control de flujo y usa a :
), y luego lo name
siguiente id:
es simplemente una declaración separada que solo contiene la variable name
(& no hace nada).
Entiendo esta regla de oro ...
Para las funciones que son transformaciones efectivas (manipulaciones de argumentos en una línea), el retorno es implícito.
Los candidatos son:
// square-root
value => Math.sqrt(value)
// sum
(a,b) => a+b
Para otras operaciones (más de una línea que requieren un bloque, el retorno debe ser explícito
Hay otro caso aquí.
Al escribir un componente funcional en React, puede usar paréntesis para ajustar JSX devuelto implícitamente.
const FunctionalComponent = () => (
<div>
<OtherComponent />
</div>
);
Aquí hay otro caso que me dio algunos problemas.
// the "tricky" way
const wrap = (foo) => (bar) => {
if (foo === 'foo') return foo + ' ' + bar;
return 'nofoo ' + bar;
}
Aquí definimos una función que devuelve una función anónima. El bit "complicado" es que el cuerpo de la función para la función externa (la parte que comienza con (bar) => ...) se ve visualmente como un "bloque", pero no lo es. Como no es así, el retorno implícito entra en juego.
Así es como se ejecutaría wrap:
// 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'));
La forma en que desempaqué esto para asegurarme de que entendí que era "desarreglar" las funciones.
Aquí está el equivalente semántico del primer bloque de código, simplemente haciendo que el cuerpo de wrap () haga un retorno explícito. Esta definición produce los mismos resultados que arriba. Aquí es donde se conectan los puntos. Compare el primer bloque de código anterior con el siguiente, y está claro que una función de flecha en sí misma se trata como una expresión, no como un bloque, y tiene el retorno implícito .
// the explicit return way
const wrap = (foo) => {
return (bar) => {
if (foo === 'foo') return foo + ' ' + bar;
return 'nofoo ' + bar;
}
}
La versión totalmente desarmado de wrap sería así, que aunque no es tan compacta como la versión con flechas gruesas, parece mucho más fácil de comprender.
// the "no arrow functions" way
const wrap = function(foo) {
return function(bar) {
if (foo === 'foo') return foo + ' ' + bar;
return 'nofoo ' + bar;
};
};
Al final, para otros que tengan que leer mi código, y para el futuro, creo que preferiría ir a la versión sin flecha que se puede comprender visualmente a primera vista, en lugar de la flecha que requiere un poco de tiempo. Pensé (y en mi caso experimentación) a grok.
Las funciones de flecha le permiten tener un retorno implícito: los valores se devuelven sin tener que usar la return
palabra clave.
Funciona cuando hay una declaración en línea en el cuerpo de la función:
const myFunction = () => 'test'
console.log(myFunction()) //'test'
Otro ejemplo, devolver un objeto (recuerde colocar los corchetes entre paréntesis para evitar que se considere los corchetes de la función de ajuste):
const myFunction = () => ({value: 'test'})
console.log(myFunction()) //{value: 'test'}