Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do multiple arrow functions mean in JavaScript?

I have been reading a bunch of React code and I see stuff like this that I don't understand:

handleChange = field => e => {   e.preventDefault();   /// Do something here } 
like image 231
jhamm Avatar asked Sep 25 '15 13:09

jhamm


People also ask

What does double arrow mean in JavaScript?

An easy way to grasp this is to remember that a curried/double arrow function is a function that implicitly returns another function(s). Going by this logic, you could also have triple arrow functions and so on.

What is the use of => in JavaScript?

In regular functions the this keyword represented the object that called the function, which could be the window, the document, a button or whatever. With arrow functions the this keyword always represents the object that defined the arrow function.

What are arrow functions in JavaScript?

Arrow function is one of the features introduced in the ES6 version of JavaScript. It allows you to create functions in a cleaner way compared to regular functions. For example, This function // function expression let x = function(x, y) { return x * y; }

What does => mean in coding?

What It Is. This is an arrow function. Arrow functions are a short syntax, introduced by ECMAscript 6, that can be used similarly to the way you would use function expressions. In other words, you can often use them in place of expressions like function (foo) {...} .


1 Answers

That is a curried function

First, examine this function with two parameters …

const add = (x, y) => x + y add(2, 3) //=> 5 

Here it is again in curried form …

const add = x => y => x + y 

Here is the same1 code without arrow functions …

const add = function (x) {   return function (y) {     return x + y   } } 

Focus on return

It might help to visualize it another way. We know that arrow functions work like this – let's pay particular attention to the return value.

const f = someParam => returnValue

So our add function returns a function – we can use parentheses for added clarity. The bolded text is the return value of our function add

const add = x => (y => x + y)

In other words add of some number returns a function

add(2) // returns (y => 2 + y) 

Calling curried functions

So in order to use our curried function, we have to call it a bit differently …

add(2)(3)  // returns 5 

This is because the first (outer) function call returns a second (inner) function. Only after we call the second function do we actually get the result. This is more evident if we separate the calls on two lines …

const add2 = add(2) // returns function(y) { return 2 + y } add2(3)             // returns 5 

Applying our new understanding to your code

related: ”What’s the difference between binding, partial application, and currying?”

OK, now that we understand how that works, let's look at your code

handleChange = field => e => {   e.preventDefault()   /// Do something here } 

We'll start by representing it without using arrow functions …

handleChange = function(field) {   return function(e) {     e.preventDefault()     // Do something here     // return ...   }; }; 

However, because arrow functions lexically bind this, it would actually look more like this …

handleChange = function(field) {   return function(e) {     e.preventDefault()     // Do something here     // return ...   }.bind(this) }.bind(this) 

Maybe now we can see what this is doing more clearly. The handleChange function is creating a function for a specified field. This is a handy React technique because you're required to setup your own listeners on each input in order to update your applications state. By using the handleChange function, we can eliminate all the duplicated code that would result in setting up change listeners for each field. Cool!

1 Here I did not have to lexically bind this because the original add function does not use any context, so it is not important to preserve it in this case.


Even more arrows

More than two arrow functions can be sequenced, if necessary -

const three = a => b => c =>   a + b + c  const four = a => b => c => d =>   a + b + c + d  three (1) (2) (3) // 6  four (1) (2) (3) (4) // 10 

Curried functions are capable of surprising things. Below we see $ defined as a curried function with two parameters, yet at the call site, it appears as though we can supply any number of arguments. Currying is the abstraction of arity -

const $ = x => k =>    $ (k (x))      const add = x => y =>    x + y    const mult = x => y =>    x * y      $ (1)           // 1    (add (2))     // + 2 = 3    (mult (6))    // * 6 = 18    (console.log) // 18      $ (7)            // 7    (add (1))      // + 1 = 8    (mult (8))     // * 8 = 64    (mult (2))     // * 2 = 128    (mult (2))     // * 2 = 256    (console.log)  // 256

Partial application

Partial application is a related concept. It allows us to partially apply functions, similar to currying, except the function does not have to be defined in curried form -

const partial = (f, ...a) => (...b) =>   f (...a, ...b)  const add3 = (x, y, z) =>   x + y + z  partial (add3) (1, 2, 3)   // 6  partial (add3, 1) (2, 3)   // 6  partial (add3, 1, 2) (3)   // 6  partial (add3, 1, 2, 3) () // 6  partial (add3, 1, 1, 1, 1) (1, 1, 1, 1, 1) // 3 

Here's a working demo of partial you can play with in your own browser -

const partial = (f, ...a) => (...b) =>    f (...a, ...b)      const preventDefault = (f, event) =>    ( event .preventDefault ()    , f (event)    )      const logKeypress = event =>    console .log (event.which)      document    .querySelector ('input[name=foo]')    .addEventListener ('keydown', partial (preventDefault, logKeypress))
<input name="foo" placeholder="type here to see ascii codes" size="50">
like image 144
Mulan Avatar answered Oct 02 '22 06:10

Mulan