5
const actionsMap = {
  [GET_USER]: (state, action) => ({ post: action.msg })
};

I have this code that I've stumbled upon. All the time I've been working with arrow functions I've seen on a {} format, what does this () wrapper mean?

Vinicius Ataide
  • 303
  • 1
  • 3
  • 11
  • Are you sure this is Javascript? It doesn't parse in my console. I think it's Coffeescript or another such derivative language. – Erik Jul 10 '15 at 16:06
  • That looks like a lambda expression, which is not supported by JS. – Mr. Polywhirl Jul 10 '15 at 16:06
  • [MDN: Arrow Functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions): *This is a new technology, part of the ECMAScript 2015 (ES6) standard . This technology's specification has been finalized, but check the compatibility table for usage and implementation status in various browsers.* An **arrow function expression** (also known as **fat arrow function**) has a shorter syntax compared to function expressions and lexically binds the this value. Arrow functions are always anonymous. – Mr. Polywhirl Jul 10 '15 at 16:09
  • 1
    So you already know the term and concept of *"arrow function"*... not sure what's left to tell you. –  Jul 10 '15 at 16:17
  • See also [ECMAScript6 arrow function that returns an object](http://stackoverflow.com/q/28770415/1048572) – Bergi Jan 09 '16 at 22:59

3 Answers3

7

With arrow functions, you can either use a single statement or a block as the function body. These two are equivalent:

() => foo
() => {
  return foo;
}

In your example, if the lambda was defined as () => {post: action.msg} the object ({}) would be interpreted as a body block instead of an object. The runtime would try to parse it as an equivalent to:

function () {
  post: action.msg
}

which is a named label and property access, and doesn't make much sense here. By wrapping in parens, you hint to the parser that it is an expression to be evaluated and the fat arrow function rules on single-expression bodies kick in, making it equivalent to:

function () {
  return {post: action.msg};
}

To work around the single-expression rules when you want to do two related things (occasionally useful in map/reduce algorithms), you can use parens to group a pair of expressions:

foo.reduce((p, c) => (c.counted = true, p += c.value));

This will set the counted property of c, before adding c.value to p and returning the result of p += c.value as the new value of p.

The parentheses wrap an expression in ECMAScript and can be used, with the comma operator, to group multiple expressions. The results of the last expression are returned when the group is evaluated.

For example:

var i = 0, j = 0;
console.log((j += 10, i += 2), j);

will print 2 10, since j is incremented in the () group and printed later.

ssube
  • 47,010
  • 7
  • 103
  • 140
  • 1
    "...which is clearly invalid." Not actually invalid in that particular case, but certainly not what was intended. –  Jul 10 '15 at 16:24
  • 2
    @squint Fixed. I always forget about labels. – ssube Jul 10 '15 at 16:29
  • thank you, this response was more detailed than the others, so I'm voting this as the correct one because it clearly means that it's an object response. the other answers are more concise and better for other people so keep checking – Vinicius Ataide Jul 10 '15 at 17:43
2

This is ES6 arrow function. More to read: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

ES6

(state, action) => ({ post: action.msg })

ES5

function(state, action) {
   return { post: action.msg };
}
Jędrzej Chałubek
  • 1,410
  • 1
  • 16
  • 29
2

From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Returning_object_literals

Returning object literals

Keep in mind that returning object literals using the concise syntax params => {object:literal} will not work as expected:

var func = () => { foo: 1 }; // Calling func() returns undefined! var func = () => { foo: function() {} }; // SyntaxError: function statement requires a name

This is because the code inside braces ({}) is parsed as a sequence of statements (i.e. foo is treated like a label, not a key in an object literal).

Remember to wrap the object literal in parentheses:

var func = () => ({ foo: 1 });

so .. if you want to return an object literal, wrap it in ()

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87