Any function which take another function as argument or return a function is called a higher-order function.
In JavaScript functions
- Can be assigned to a variable.
- Can be passed as argument to another function.
- Can be returned by another function.
- Can be set as object properties.
- Can be passed in an array element.
Lets look at each one with examples.
1. Function assigned to a variable
// Function assigned to a variable
let fullName = function(fname, lname){
return (`${fname}${lname}`);
}
fullName();
In the above code a unnamed function is assigned to a variable "fullName". We can invoke the function by calling fullName();
2. Function passed as argument to another function
// Function passed as argument to another function
let fullName = function(fname, lname){
return (`${fname}${lname}`);
}
function createEmail(fn,ln, fun1){
let full_name = fun1(fn,ln);
return ${full_name}@gmail.com`;
}
let pass = createEmail("kiran", "raj",fullName)
In the above example function "FullName" is passed as parameter to "createEmail" function.
3. Function return another function
// Function return another function
function calc(x,y, fun1, fun2){
let r1 = fun1(x,y);
let r2 = fun2(x,y);
console.log(`${x} * ${y} = ${r1}`);
console.log(`${x} / ${y} = ${r2}`);
return function() {
console.log(`${x} + ${y} = ${x + y}`);
console.log(`${x} - ${y} = ${x - y}`);
}
}
calc(20,10, multiply, divide)();
// 20 * 10 = 200
// 20 / 10 = 2
// 20 + 10 = 30
// 20 - 10 = 10
In the above function function calc returns a function, the returned function can be called using double invocation.
4. Function passed as value of object property
// Function passed as value of object property
let admin1 = {
fname: "kiran",
lname: "raj",
greetAdmin : function(){
console.log(`Hello ${this. fname} ${this.lname}`);
}
}
In the above code a unnamed method is passed as a value of object property, "greetAdmin". It can be invoked by calling admin1.greetAdmin().
5. Function passed as array element
// Function passed as array element
const divide = function(x,y){ return x/y; };
const multiply = function(x,y){ return x*y; };
const add = function(x,y){ return x + y; };
const substract = function(x,y){ return x - y; };
let calc_arr = [divide, multiply, add, substract];
console.log(calc_arr[0](10,20)); // 0.5
console.log(calc_arr[1](10,20)); // 200
console.log(calc_arr[2](10,20)); // 30
console.log(calc_arr[3](10,20)); // -10
Higher-order functions in JavaScript
- Array.prototype.map
- Array.prototype.filter
- Array.prototype.reduce
- Array.prototype.forEach
- Array.prototype.every
- Array.prototype.some
Array.prototype.map
returns a new array with the results of callback applied to every element
Map method creates a new array with result of invoking the callback once for each element of the array, in the order of the array. A new array is returned, there will be no change to the original array. The map() method takes a function as argument, the function has three arguments currentValue, index and array. The function will not be called for deleted indexes and indexes not set. Any element added to the array after first invocation of the callback will be ignored.
// Syntax
arr.map(callback(currentVal, index ,array) {
// code to execute
}),thisArg;
arr represent the array in which the map is called, callback is called for every element of arr. index, array, and thisArg are all optional. Index refers to the index of the current element being passed to the callback, array represent the array in which map is called and thisArg, the value to be used for "this" when executing the callback. If "thisArg" is not provided "this" will be set to "undefined".
let arr1 = [2,4,6,8,11,5];
let arr_map = arr1.map( elem => elem*elem);
console.log(arr_map); //[4, 16, 36, 64, 121, 25]
console.log(arr1); //[2, 4, 6, 8, 11, 5]
In the above code a new array "arr_map" is returned with square of the elements of arr1 using the map method. The equivalent code of the above is given below.
let arr1 = [2,4,6,8,11,5];
let arr_map = [];
for (i =0; i< arr1.length; i++){
arr_map.push(arr1[i]*arr1[i]);
}
console.log(arr_map) //[4, 16, 36, 64, 121, 25]
console.log(arr1); //[2, 4, 6, 8, 11, 5]
Higher-order functions are easy to implement and less number of statements.
let arr1 = [2,4,6,8,11,5];
let arr2_map = arr1.map((elem, index, a) => {
console.log(`Element ${elem} Index ${index} Array ${a}`);
// Element 2 Index 0 Array 2,4,6,8,11,5
// Element 4 Index 1 Array 2,4,6,8,11,5
// Element 6 Index 2 Array 2,4,6,8,11,5
// Element 8 Index 3 Array 2,4,6,8,11,5
// Element 11 Index 4 Array 2,4,6,8,11,5
// Element 5 Index 5 Array 2,4,6,8,11,5
});
Lets look at one more example.
var names = ["kiran", "vishnu", "manu", "varun", "adi"];
let names_cap = names.map((index)=>{
return index.charAt(0).toUpperCase()+ index.slice(1);
})
console.log(names_cap);
//["Kiran", "Vishnu", "Manu", "Varun", "Adi"]
Top comments (2)
Hi, Kiran.
I must confess that your article raises some questions regarding the example posted under item "3. Function return another function". I don't see the point in declaring arguments "fun1" and "fun2" for function "calc" if there is no further reference to any of them inside the declaration. While I'm no expert in Java Script, my personal experience would indicate that the code for function "calc" should be something like:
Again, I am no expert in JavaScript, my point is that the passing of arguments to a function should be recognized -utilized, employed- inside the definition of the function; as shown, in your example under "3. Function return another function", I cannot relate the arguments passed to the result obtained.
Yours is an excellent article, Kiran, and my only intention is to express my very personal doubts on the matter. Thank you.
Dear Hector, thank you for pointing out the mistake, I edited the example. Please check the edit. Like you I am also not an expert, just like to share things I know, to others. If there are errors please feel free to point it out, that will help us to learn better. Good day!!!