When should I use `return` in es6 Arrow Functions?

后端 未结 5 2228
后悔当初
后悔当初 2020-11-21 05:40

The new es6 arrow functions say return is implicit under some circumstances:

The expression is also the implicit return value of that fun

相关标签:
5条回答
  • 2020-11-21 05:47

    Jackson has partially answered this in a similar question:

    Implicit return, but only if there is no block.

    • This will result in errors when a one-liner expands to multiple lines and the programmer forgets to add a return.
    • Implicit return is syntactically ambiguous. (name) => {id: name}returns the object {id: name}... right? Wrong. It returns undefined. Those braces are an explicit block. id: is a label.

    I would add to this the definition of a block:

    A block statement (or compound statement in other languages) is used to group zero or more statements. The block is delimited by a pair of curly brackets.

    Examples:

    // 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') 
    
    0 讨论(0)
  • 2020-11-21 05:59

    Arrow functions allow you to have an implicit return: values are returned without having to use the return keyword.

    It works when there is a on-line statement in the function body:

    const myFunction = () => 'test'
    
    console.log(myFunction()) //'test'

    Another example, returning an object (remember to wrap the curly brackets in parentheses to avoid it being considered the wrapping function body brackets):

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

    0 讨论(0)
  • 2020-11-21 06:05

    I understand this rule-of-thumb ...

    For functions that are effectively transforms (one-line-manipulations of arguments), return is implicit.

    Candidates are:

    // square-root 
    value => Math.sqrt(value)
    
    // sum
    (a,b) => a+b
    

    For other operations (more than one-liners that require a block, return has to be explicit

    0 讨论(0)
  • 2020-11-21 06:06

    There's another case here.

    When writing a functional component in React, you can use parentheses to wrap implicitly returned JSX.

    const FunctionalComponent = () => (
      <div>
        <OtherComponent />
      </div>
    );
    
    0 讨论(0)
  • 2020-11-21 06:06

    Here's another case that gave me some trouble.

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

    Here we define a function returning an anonymous function.The "tricky" bit is that the function body for the outer function (the part begining with (bar) => ...) visually looks like a "block", but it's not. Since it's not, implicit return kicks in.

    Here's how wrap would execute:

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

    The way I unpacked this to make sure I understood it was to "unarrowify" the functions.

    Here's the semantic equivalent of the first code block, simply making the body of wrap() do an explicit return. This definition produces the same results as above. This is where the dots connect. Compare the first code block above with the one below, and it's clear that an arrow function itself is treated as an expression, not a block, and has the implied return.

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

    The fully unarrowified version of wrap would be like this, which while not as compact as the fat arrowed up version, seems a lot easier to comprehend.

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

    In the end, for others that may have to read my code, and future me, I think I'd prefer to go the non arrow version which can be comprehended visually at first glance, rather than the arrow one which takes a fair bit of thought (and in my case experimentation) to grok.

    0 讨论(0)
提交回复
热议问题