what do multiple arrow functions mean in javascript?

  • Last Update :
  • Techknowledgy :

Multiple arrow functions are also called "curried functions" and they are used for function compositions. An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value. Arrow functions are always anonymous. 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 - The example in your question is that of a curried function which makes use of arrow function and has an implicit return for the first argument.

This is our Splunktool team suggestion, we tried and its working fine ✌
const add = x => y => x + y
//is
const add = function(x) {
   return function(y) {
      return x + y
   }
}

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

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)

Suggestion : 2

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. Double Arrow functions are actually curried functions. Consider the following code snippet to understand Therefore we make use of a curried function which returns another function having its own scope of variables without any global variables.


Arrow functions are anonymous functions that are special because they do not bind to their own this. They get the value of this from the enclosing context. They also provide a more concise syntax.

Here is a simple example of an arrow function which explicitly returns a value. (it is called an explicit return because we made use of the keyword return.)

const sayHello = (name) => {
   return `Hello ${name}`;
}

console.log(sayHello('Stephen')); // Hello Stephen

If your function is expected to return a simple value, you can use implicit return, i.e. returning something without using the return keyword.

const sayHello = (name) => `Hello ${name}`;

console.log(sayHello('Stephen')); // Hello Stephen
3._
// A simple arrow function
const myFunction = (x, y) => {
   console.log('param1', x);
   console.log('param2', y);
}

// The same function in curried form or as you say, double arrow function
const myFunction = x => y => {
   console.log('param1', x);
   console.log('param2', y);
}

// The above function without using arrow functions - 
function myFunction(x) {
   return function innerFunction(y) {
      console.log('param1', x);
      console.log('param2', y);
   }
}

This is best explained with the help of an example. Assume that we want to write an onClick handler. The onClick event handler receives only 1 parameter by default i.e. the event. But what if we also wanted to pass another parameter, say Id to it ?

If you try something like this, it won’t work and the Id will be undefined.

const handleClick = (e, id) {
   event.preventDefault()
   // id will be undefined
}
6._
const handleClick = id => event {
  event.preventDefault();

  // do something with the received ID
  console.log('ID received', id); 
}

// within your html
<button onClick=handleClick('45')>

Suggestion : 3

Simply put, the use of multiple arrow functions in JavaScript means that you are creating a closure which is a function that returns another function. This is because arrow functions return whatever their right hand value is after the “arrow” part of the notation, so if another function is provided, then it will return that function. This means that if we have another arrow function on the right hand side we are then returning the second arrow function which will then create a closure. Arrow functions that use multiple functions in a row are simply creating a closure.

1._
const exampleFunction = () => () => {
   console.log("Hello World!")
}
2._
const addNumbers = a => b => a + b
addNumbers(2)(2) // 4

// or

const addTwo = addNumbers(2) // function (b) => (2 + b)
addTwo(2) // 4
3._
const addNumbers = a => b => a + b
const addTwo = addNumbers(2) // function (b) => (2 + b)
// 2 will now be persisted when the addTwo function is used.

Suggestion : 4

A simple ES6 function that demonstrates it:- The above code explains what is going on with multiple arrow operators. It returns a function which in turn accepts a parameter, the nested returned function maintains the state of x. This methodology is called currying. We may have come across arrow functions in javascript and are almost saturated learning about the difference between normal functions and arrow functions, the difference between ES5 and ES6 and everything that is connected to it. But everytime we come across multiple arrows in a single function, we keep struggling - or it could just be a "me" problem. Here goes, what multiple arrows in a function mean.

1._
const add = x => y => x + y
2._
function add(x) {
   return function(y) {
      return x + y
   }
}
3._
add(2)(3)
// This would return 5

Suggestion : 5

Note: Traditional function expressions and arrow functions have more differences than their syntax. We will introduce their behavior differences in more detail in the next few subsections. Although the arrow in an arrow function is not an operator, arrow functions have special parsing rules that interact differently with operator precedence compared to regular functions. Let's decompose a traditional anonymous function down to the simplest arrow function step-by-step. Each step along the way is a valid arrow function.

1._
param => expression

(param) => expression

   (param1, paramN) => expression

param => {
   statements
}

(param1, paramN) => {
   statements
}
2._
(a, b, ...r) => expression
   (a = 400, b = 20, c) => expression([a, b] = [10, 20]) => expression({
      a,
      b
   } = {
      a: 10,
      b: 20
   }) => expression
3._
async param => expression
async (param1, param2, ...paramN) => {
   statements
}
5._
// Traditional anonymous function
(function(a, b) {
   return a + b + 100;
});

// Arrow function
(a, b) => a + b + 100;

const a = 4;
const b = 2;

// Traditional anonymous function (no parameters)
(function() {
   return a + b + 100;
});

// Arrow function (no arguments)
() => a + b + 100;
6._
// Traditional anonymous function
(function(a, b) {
   const chuck = 42;
   return a + b + chuck;
});

// Arrow function
(a, b) => {
   const chuck = 42;
   return a + b + chuck;
};

Suggestion : 6

As you can see, (a, b) => a + b means a function that accepts two arguments named a and b. Upon the execution, it evaluates the expression a + b and returns the result. This creates a function func that accepts arguments arg1..argN, then evaluates the expression on the right side with their use and returns its result. Without curly braces: (...args) => expression – the right side is an expression: the function evaluates it and returns the result. Parentheses can be omitted, if there’s only a single argument, e.g. n => n*2.

1._
let func = (arg1, arg2, ..., argN) => expression;
2._
let func = function(arg1, arg2, ..., argN) {
   return expression;
};
3._
let sum = (a, b) => a + b;

/* This arrow function is a shorter form of:

let sum = function(a, b) {
  return a + b;
};
*/

alert(sum(1, 2)); // 3
5._
let sayHi = () => alert("Hello!");

sayHi();
6._
let age = prompt("What is your age?", 18);

let welcome = (age < 18) ?
   () => alert('Hello!') :
   () => alert("Greetings!");

welcome();

Suggestion : 7

Inside functions used as callbacks for event listeners, this holds the value of the element that fired the event.   Arrow functions, introduced in ES6, provides a concise way to write functions in JavaScript. Another significant advantage it offers is the fact that it does not bind its own this. In other words, the context inside arrow functions is lexically or statically defined.What do we mean by that? Unlike other functions, the value of this inside arrow functions is not dependent on how they are invoked or how they are defined. It depends only on its enclosing context. Let us try to understand with an example:  bind(), call() and apply() are all used to modify the context of a function. All three of these help explicitly specify what the value of this should be inside a function. But, there are certain differences in how each of them work. Let us study these differences. 

1._
<!DOCTYPE html>
<html>
<body>
<script>
    let People = function(person, age) {
        this.person = person;
        this.age = age;
        this.info = function() {
  
         // logs People
         document.write(this);
  
         setTimeout(function() {
            // here this!=People
           document.write(this.person + " is " + this.age + 
                                              " years old");
          }, 3000);
        }
    } 
   let person1 = new People('John', 21);
  
// logs : undefined is undefined years old after 3 seconds
person1.info();
</script>      
</body>
</html>

Output: 
 

[object Object]
undefined is undefined years old
3._
<!DOCTYPE html>
<html>
<body>
<script>
    let People = function(person, age) {
        this.person = person;
        this.age = age;
        this.info = function() {
  
            // logs People
            document.write(this); 
  
           setTimeout(() => { 
            // arrow function to make lexical "this" binding
            // here this=People."this" has been inherited
            document.write(this.person + " is " + this.age 
                                           + " years old");
           }, 3000);
        }
    } 
let person1 = new People('John', 21);
  
// logs : John is 21 years old after 3 seconds
person1.info(); 
</script>                    
</body>
</html>  
7._
<!DOCTYPE html>
<html>
<body>
<script>
    let People = function(person, age) {
        this.person = person;
        this.age = age;
        this.info = function() {
  
            // logs People
            document.write(this + ' ');
  
            // here this=People
            document.write(this.person + " is " + this.age + 
                                    " years old" + '<br>');
  
        }
    }
  
let person1
    = new People('John', 21);
  
// logs : John is 21 years old
person1.info();
  
let separated = person1.info.bind(person1);
  
/*
the bind(person1) statement ensures that "this" always
refers to person1 inside the bound method- info()
*/
  
// logs : undefined is undefined years old
separated();
</script>                    
</body>
</html>

bind() allows us to explicitly define what value this will have inside a function by binding an object to that function. 
The bound object serves as the context(this value) for the function that it was bound to. 
To use it, we need primarily two things – An object to bind to a function and a function that this object is to be bound to.
The general syntax for bind is : 
 

boundfunction = someFunction.bind(someObject, additionalParams);

Suggestion : 8

Thus they created dynamically. We cannot name an arrow function as we do for the regular functions. However, if you’d like to call or reuse an arrow function, you will need to assign it to a variable. The arrow functions concept is great, however, they are not ideal across all functional instances. You should be keen on where to apply the arrow function. Arrow functions are not attached to an identifier (the function name). To call or reuse them, your need to assign them to a variable.

1._
// a named regular function
function myFunc(params) {
   // function body
}
2._
// anonymous arrow function
(params) => {
   // function body
};
3._
const myFunc = (params) => {
   // function body
}
5._
function square(a) {
   return a * a;
}
6._
const square = (a) => {
   return a * a;
}