Categories
arrow-functions ecmascript-6 javascript

When should I use a return statement in ES6 arrow functions

198

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

The expression is also the implicit return value of that function.

In what cases do I need to use return with ES6 arrow functions?

    311

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

    7

    • I don’t get that syntax.. are you creating a class using a class littoral and then calling an implied constructor with one argument (‘Jess’)?? I thought you would to this ((name) => ({id: ‘Jess’}))

      Jul 14, 2015 at 8:50

    • 4

      @MichaelDausmann It’s an arrow function that has one parameter, name, with the function enclosed in parentheses and invoked with one argument, “Jess”. Code between the => and )('Jess') in each case is the body of the arrow function. Consider it like a short form of an Immediately Invoked Function Expression of the form (function (name) { return { id: name } })('Jess')

      – Russ Cam

      Jul 14, 2015 at 12:59

    • Very useful indded! helps spot problems in Promises.all that map over items with an arrow function and you can notice if you get an array of undefined if no value was returned for mapping over array with arrow functions.

      – jay shah

      Oct 6, 2016 at 13:07

    • What would have been the downside of making implicit return systematic for arrow functions? Just like coffeescript does… (though I don’t like coffeescript)

      Feb 16, 2017 at 16:04

    • 8

      To be clear, it seems that because the JS parser doesn’t know whether to expect an expression (such as an expression containing an object literal {}) or a block, it assumes that a { } denotes a block. That means that when it sees id: name, it thinks id: is an expression creating a label (a very uncommonly-used feature of JS that deals with flow control and uses a :), and then the name following id: is simply a separate statement that only contains the variable name (& does nothing).

      – iono

      Jul 31, 2018 at 17:32

    25

    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

      13

      There’s another case here.

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

      const FunctionalComponent = () => (
        <div>
          <OtherComponent />
        </div>
      );
      

      1

      • 16

        You can always use parentheses, it’s unrelated to JSX or React.

        Jul 2, 2019 at 21:02