Question

I've been trying to learn some of the new features of ES6, and while most of it makes sense, I'm having trouble grasping the arrow function. I'm not asking so much why it exists as I am how to read it.

Previously in JS, when a function was defined, the syntax reads really nicely.

var foo = function(property) { return property + 'bar' } says: define a variable 'foo' that is a function that returns property + 'bar'.

Alternatively, function foo(property) {} roughly reads as: define a function named foo that has a property.

But when I see something with an arrow function:

const foo = (property) => { return property + 'bar' }

How do I read that? Define a constant 'foo' that equals...a property...that equals...returning a property plus 'bar'?

Then, probably because I don't fully understand this concept, I get to a line like this and get pretty lost:

const actionLogger = ({dispatch, getState}) => (next) => (action) => { console.log(action); return next (action) }

In a Redux instructional video, the author switches to arrow functions because it 'has clearer semantics in ES6', so I just want to understand the semantics of arrow functions!

Was it helpful?

Solution

const foo = (property) => { return property + 'bar' }

In JavaScript, functions are objects. That means they can be passed around and assigned to variables (I mean, other languages support it too and are adapting it more and more, but JavaScript is pretty much build on that).

In order to understand ES6 fat arrow functions, it's good to know what the function expands to as well as the few new rules that come with ES6 anonymous functions, such as:

  • lexical this
  • implicit return
  • not having to use brackets for a single parameter functions

With that knowledge in mind the mentioned piece of code may look like any of the following variants:

const foo = property => { return property + 'bar' }
const foo = (property) => property + 'bar'
const foo = property => property + 'bar'

And it all expands to:

var foo = function(property) {
    return property + 'bar'
}

If you are familiar with pointers in languages like C or C++, what the fat arrow syntax does is it creates a function and returns a function pointer to it which may be assigned to a variable on the left side of the equation.

That is the main thing you got wrong, you are not returning some magical property which is assigned to the constant foo variable, the property is a function, and that's it.

So while the initial Redux code might look a little off-putting at first it really expands to nothing else than a few chained functions within each other.

var actionLogger = function actionLogger(input) {
  var dispatch = input.dispatch;
  var getState = input.getState;

  return function (next) {
    return function (action) {
      console.log(action);
      return next(action);
    };
  };
};

The actions logger is then called like this:

// You pass a dispatch and getState variables to it
var dispatchedLogger = actionLogger({dispatch: someDispatch, getState: someState});

// You define a function that is supposed to fire after each action
// Each action type will be modified by apending 'bar' to it
var withFollowUpAction = dispatchedLogger(action => action + 'bar');

// Finally you run it with the desired action
withFollowUpAction('someAction');

Now I haven't really worked with Redux, but I believe the reason why the functions are chained the way they are is because of the API of the Redux library, which knows how to consume it.

OTHER TIPS

const foo = (property) => { return property + 'bar' }

How do I read that?

Define a constant foo that equals a function which takes an argument, property, and returns property + bar.

In general,

(...) => { ... }

is mostly equivalent to

function(...) {...}

(there are difference in terms of how this is handled.)

So the above is almost equivalent to:

const foo = function(property) {return property + 'bar'}

But, we could also write it:

const foo = (property) => property + 'bar'

If the => isn't followed by a { then it defines a function that returns a javascript expression. So, without the {

(...) => ...

Is mostly equivalent to

function(...) => {return ...}

For the redux examples:

const actionLogger = ({dispatch, getState}) => (next) => (action) => { 
  console.log(action); return next (action) 
}

Let's expand it out:

const actionLogger = function({dispatch, getState}) {
    return function(next) {
        return function(action) {
            console.log(action)
            next(action);
        }
    }
}

The Redux example is a bit confusing because it does something a little odd. Its defining a function that returns a function that itself returns another function. I believe Redux does this because its imitating the currying feature found in functional languages, although I find it out of place here.

Licensed under: CC-BY-SA with attribution
scroll top