34

I've seen JavaScript code such as this:

let a = () => ({ id: 'abc', name: 'xyz' })

What do the parentheses ( … ) wrapping the object refer to in this instance? Is it a shorthand for return?

Boann
  • 48,794
  • 16
  • 117
  • 146
Stanley
  • 2,798
  • 5
  • 22
  • 44
  • 2
    A syntax error will be thrown without `()` surrounding `{ id: 'abc', name: 'xyz' }`, `({ id: 'abc', name: 'xyz' })` is an expression – guest271314 Jul 10 '17 at 04:23
  • 3
    @xufox OPs title is poor. He's asking about the rhs wrapping parenths, not the parameterless lambda parenths on the lhs. – StuartLC Jul 10 '17 at 04:27
  • 3
    Because curly braces are used to denote the function’s body, an arrow function that wants to return an object literal outside of a function body must wrap the literal in parentheses. Found that info here: https://www.nczonline.net/blog/2013/09/10/understanding-ecmascript-6-arrow-functions/ ... down in the page before Usage. – Paul T. Jul 10 '17 at 04:32
  • Welcome to Ecmascript 2 0 1 5 ! –  Jul 10 '17 at 07:31

2 Answers2

58

No. Those parentheses produce an object literal. Arrow functions have many syntaxes, one of which is:

( … ) => expression

This will implicitly return an expression, for example:

() => 1 + 1

This function will implicitly return 1 + 1, which is 2. Another one is this:

( … ) => { … }

This will create a block to house multiple statements if you don't want to implicitly return an expression, and if you want to do intermediate calculations or not return a value at all. For example:

() => {
  const user = getUserFromDatabase();
  console.log(user.firstName, user.lastName);
}

The problem arises when you want to implicitly return an object literal. You can't use ( … ) => { … } because it'll be interpreted as a block. The solution is to use parentheses.

The parentheses are there for the { … } to be interpreted an object literal, not a block. In the grouping operator, ( … ), only expressions can exist within them. Blocks are not expressions but object literals are, thus an object literal is assumed. Thus, instead of creating a block, it will use this syntax:

( … ) => expression

And implicitly return an object literal. Without the parentheses, it will be interpreted as labels and strings, not keys and values of an object literal.

let a = () => { 
  id: 'abc', //interpreted as label with string then comma operator
  name: 'xyz' // interpreted as label (throws syntax error)
}

The comma here would be interpreted as the comma operator, and since the operands must be expressions, and labels are statements, it will throw a syntax error.

Andrew Li
  • 55,805
  • 14
  • 125
  • 143
  • 1
    This answer is correct, except that I don't understand your statement that "Those parentheses also aren't wrapping an object literal, but *produce* an object literal." It seems to me that wrapping the object literal is *exactly* what the parentheses are doing. The object literal needs to be wrapped in parentheses for the reason you give in your answer. – ruakh Jul 11 '17 at 03:45
  • @ruakh I know it's a bit late (a year late) but I didn't ever get around to editing this answer for some reason. I agree it is confusing. Removed the first clause. – Andrew Li Jul 22 '18 at 18:23
12

It allows you to create an expression, so

let a = () => ({ id: 'abc', name: 'xyz' })

specifies that a when invoked, returns the enclosed object

If you remove the () in this case, it will throw an error because it is not a valid function body statement, because the {} in let a = () => { id: 'abc', name: 'xyz' } are interpreted as the boundaries of a statement, but the content inside is not valid if you look at it.

let a = () => {
    id: 'abc',    /* Not valid JS syntax */
    name: 'xyz'
}
Trash Can
  • 6,608
  • 5
  • 24
  • 38
  • 3
    So is it correct to say that `let a = () => ({ id: 'abc', name: 'xyz' })` is the same as `let a = () => {return ({ id: 'abc', name: 'xyz' })}` and then also `let a = () => {return {id: 'abc', name: 'xyz' }}`? – Mallory-Erik Jan 30 '18 at 13:20
  • 1
    @Mallory-Erik Yeep – Trash Can Jan 30 '18 at 16:54