3

I wanted to return an object from an arrow function, but the code below was returning undefined. I realized that the curly braces were being interpreted as beginning/ending the function body. What intrigues me is why a: 1 didn’t throw an error.

const foo = () => {a: 1};
foo();
// > undefined
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Eduardo Matos
  • 741
  • 2
  • 6
  • 14

1 Answers1

6

The issue is that the parser sees a label called 'a' which belongs to the expression statement '1'. Since there's no return statement at all, the returned value is always undefined.

If you wrap the body inside '()' you'll see your object being returned, see below.

const foo = () => ({a: 1});
console.log(foo());

Edit: By adding the parentheses you are forcing the parser to treat the object literal as an expression so that it's not treated as a block statement.

Eduardo Matos
  • 741
  • 2
  • 6
  • 14
Adrian
  • 8,271
  • 2
  • 26
  • 43
  • 1
    This is the correct answer but to add, there is an ambiguity between returning an object literal and using braces to open the function. The latter takes precedence and sets up the label situation. The parens just make it clear what you mean. – ktilcu Nov 14 '17 at 15:00
  • @ktilcu Thanks, I have edit the answer with a little more clarification. – Adrian Nov 14 '17 at 15:02
  • To be even clearer: the function body following `=>` is treated as a block if it’s surrounded by `{`…`}`, so everything will be in statement context. That’s why you need a `return`, that’s why `a` is interpreted as a label. Without the surrounding curly braces, everything will be evaluated in expression context. That’s when `return` becomes optional, that’s when `{a: 1}` is interpreted as an object. – Sebastian Simon Nov 14 '17 at 15:11