Skip to content

Commit b0da61e

Browse files
hofs in js
1 parent d98afad commit b0da61e

File tree

4 files changed

+323
-2
lines changed

4 files changed

+323
-2
lines changed

HigherOrderFunction/index.js

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
2+
// Higher Order Functions in JavaScript
3+
4+
// 1. What is a Higher Order Function?
5+
// A higher order function is a function that either takes one or more functions as arguments, or returns a function as its result.
6+
7+
// Example 1: Passing a function as an argument
8+
function greet(name) {
9+
return `Hello, ${name}!`;
10+
}
11+
12+
function processUserInput(callback) {
13+
const name = 'Aditya';
14+
return callback(name);
15+
}
16+
17+
console.log(processUserInput(greet)); // Output: Hello, Aditya!
18+
19+
// Example 2: Returning a function
20+
function multiplier(factor) {
21+
return function(number) {
22+
return number * factor;
23+
};
24+
}
25+
26+
const double = multiplier(2);
27+
console.log(double(5)); // Output: 10
28+
29+
// 2. Why use Higher Order Functions?
30+
// - Abstraction: Hide details and expose only necessary parts.
31+
// - Reusability: Write generic functions that work with other functions.
32+
// - Functional Programming: Enables techniques like map, filter, reduce.
33+
34+
// 3. Built-in Higher Order Functions
35+
const numbers = [1, 2, 3, 4, 5];
36+
37+
// map: transforms each element
38+
const squares = numbers.map(x => x * x);
39+
console.log(squares); // [1, 4, 9, 16, 25]
40+
41+
// filter: selects elements based on condition
42+
const evens = numbers.filter(x => x % 2 === 0);
43+
console.log(evens); // [2, 4]
44+
45+
// reduce: accumulates values
46+
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
47+
console.log(sum); // 15
48+
49+
// 4. Custom Higher Order Function Example
50+
function repeat(n, action) {
51+
for (let i = 0; i < n; i++) {
52+
action(i);
53+
}
54+
}
55+
56+
repeat(3, console.log); // Logs 0, 1, 2
57+
58+
// 5. Returning Functions (Closures)
59+
function makeCounter() {
60+
let count = 0;
61+
return function() {
62+
count++;
63+
return count;
64+
};
65+
}
66+
67+
const counter = makeCounter();
68+
console.log(counter()); // 1
69+
console.log(counter()); // 2
70+
71+
// 6. Practical Example: Function Composition
72+
function compose(f, g) {
73+
return function(x) {
74+
return f(g(x));
75+
};
76+
}
77+
78+
const add1 = x => x + 1;
79+
const times2 = x => x * 2;
80+
const add1ThenTimes2 = compose(times2, add1);
81+
console.log(add1ThenTimes2(5)); // (5 + 1) * 2 = 12
82+
83+
84+
const radius = [1, 2, 3, 4];
85+
const calculateArea = function (radius) {
86+
const output = [];
87+
for (let i = 0; i < radius.length; i++) {
88+
output.push(Math.PI * radius[i] * radius[i]);
89+
}
90+
return output;
91+
};
92+
console.log(calculateArea(radius));
93+
94+
const calculateCircumference = function (radius) {
95+
const output = [];
96+
for (let i = 0; i < radius.length; i++) {
97+
output.push(2 * Math.PI * radius[i]);
98+
}
99+
return output;
100+
};
101+
console.log(calculateCircumference(radius));
102+
103+
const radiusArr = [1, 2, 3, 4];
104+
105+
// logic to calculate area
106+
const area = function (radius) {
107+
return Math.PI * radius * radius;
108+
}
109+
110+
// logic to calculate circumference
111+
const circumference = function (radius) {
112+
return 2 * Math.PI * radius;
113+
}
114+
115+
const calculate = function(radiusArr, operation) {
116+
const output = [];
117+
for (let i = 0; i < radiusArr.length; i++) {
118+
output.push(operation(radiusArr[i]));
119+
}
120+
return output;
121+
}
122+
console.log(calculate(radiusArr, area));
123+
console.log(calculate(radiusArr, circumference));
124+
// Over here calculate is HOF
125+
// Over here we have extracted logic into separate functions. This is the beauty of functional programming.
126+
// We can also use built-in higher order functions like map to achieve the same result
127+
const areas = radiusArr.map(area);
128+
console.log(areas);
129+
const circumferences = radiusArr.map(circumference);
130+
console.log(circumferences);
131+
132+
133+
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# Higher Order Functions in JavaScript
2+
3+
## What is a Higher Order Function?
4+
A higher order function is a function that either:
5+
- Takes one or more functions as arguments
6+
- Returns a function as its result
7+
for eg.
8+
9+
```js
10+
function x() {
11+
console.log("Hi");
12+
};
13+
function y(x) {
14+
x();
15+
};
16+
y(); // Hi
17+
// y is a higher order function
18+
// x is a callback function
19+
```
20+
21+
## Why use Higher Order Functions?
22+
- **Abstraction:** Hide details and expose only necessary parts
23+
- **Reusability:** Write generic functions that work with other functions
24+
- **Functional Programming:** Enables techniques like map, filter, reduce
25+
26+
## Examples
27+
28+
### 1. Passing a function as an argument
29+
```js
30+
function greet(name) {
31+
return `Hello, ${name}!`;
32+
}
33+
function processUserInput(callback) {
34+
const name = 'Aditya';
35+
return callback(name);
36+
}
37+
console.log(processUserInput(greet)); // Output: Hello, Aditya!
38+
```
39+
40+
### 2. Returning a function
41+
```js
42+
function multiplier(factor) {
43+
return function(number) {
44+
return number * factor;
45+
};
46+
}
47+
const double = multiplier(2);
48+
console.log(double(5)); // Output: 10
49+
```
50+
51+
### 3. Built-in Higher Order Functions
52+
There are various built in HOFs, and some of the most common ones are map(), filter() and reduce().
53+
54+
- **map** is a method that we use to apply a function to each element in an array, and it returns a new array with the modified elements.
55+
56+
- The **filter()** function takes an array and returns a new array with only the values that meet certain criteria. It also does not mutate the original array. It is often used to select a subset of data from an array based on certain criteria.
57+
58+
- The **reduce()** method in JavaScript is an array method that executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The result is a single output value.
59+
60+
```js
61+
const numbers = [1, 2, 3, 4, 5];
62+
const squares = numbers.map(x => x * x); // [1, 4, 9, 16, 25]
63+
const evens = numbers.filter(x => x % 2 === 0); // [2, 4]
64+
const sum = numbers.reduce((acc, curr) => acc + curr, 0); // 15
65+
```
66+
67+
### 4. Custom Higher Order Function Example
68+
```js
69+
// repeat is a higher order function because it takes another function (action) as an argument
70+
function repeat(n, action) {
71+
for (let i = 0; i < n; i++) {
72+
action(i); // action is called for each value of i
73+
}
74+
}
75+
// Here, console.log is passed as the action, so it logs 0, 1, 2
76+
repeat(3, console.log); // Logs 0, 1, 2
77+
```
78+
79+
### 5. Returning Functions (Closures)
80+
```js
81+
// makeCounter returns a function, so it's a higher order function
82+
// The returned function forms a closure over the count variable
83+
function makeCounter() {
84+
let count = 0;
85+
return function() {
86+
count++; // count is remembered between calls
87+
return count;
88+
};
89+
}
90+
const counter = makeCounter();
91+
console.log(counter()); // 1
92+
console.log(counter()); // 2
93+
// Each call to counter() increases and returns the count
94+
```
95+
96+
### 6. Function Composition
97+
```js
98+
// compose is a higher order function that takes two functions and returns a new function
99+
function compose(f, g) {
100+
return function(x) {
101+
return f(g(x)); // applies g to x, then f to the result
102+
};
103+
}
104+
const add1 = x => x + 1;
105+
const times2 = x => x * 2;
106+
const add1ThenTimes2 = compose(times2, add1);
107+
console.log(add1ThenTimes2(5)); // (5 + 1) * 2 = 12
108+
// add1ThenTimes2 first adds 1 to 5, then multiplies the result by 2
109+
```
110+
111+
## Interview Approach Example: Calculating Area and Circumference
112+
113+
### First Approach (Not DRY)
114+
```js
115+
const radius = [1, 2, 3, 4];
116+
const calculateArea = function (radius) {
117+
const output = [];
118+
for (let i = 0; i < radius.length; i++) {
119+
output.push(Math.PI * radius[i] * radius[i]);
120+
}
121+
return output;
122+
};
123+
console.log(calculateArea(radius));
124+
125+
const calculateCircumference = function (radius) {
126+
const output = [];
127+
for (let i = 0; i < radius.length; i++) {
128+
output.push(2 * Math.PI * radius[i]);
129+
}
130+
return output;
131+
};
132+
console.log(calculateCircumference(radius));
133+
```
134+
135+
### Better Approach Using Higher Order Function
136+
```js
137+
const radiusArr = [1, 2, 3, 4];
138+
139+
// logic to calculate area
140+
const area = function (radius) {
141+
return Math.PI * radius * radius;
142+
}
143+
144+
// logic to calculate circumference
145+
const circumference = function (radius) {
146+
return 2 * Math.PI * radius;
147+
}
148+
149+
const calculate = function(radiusArr, operation) {
150+
const output = [];
151+
for (let i = 0; i < radiusArr.length; i++) {
152+
output.push(operation(radiusArr[i]));
153+
}
154+
return output;
155+
}
156+
console.log(calculate(radiusArr, area));
157+
console.log(calculate(radiusArr, circumference));
158+
// Over here calculate is HOF
159+
// Over here we have extracted logic into separate functions. This is the beauty of functional programming.
160+
161+
// We can also use built-in higher order functions like map to achieve the same result
162+
const areas = radiusArr.map(area);
163+
console.log(areas);
164+
const circumferences = radiusArr.map(circumference);
165+
console.log(circumferences);
166+
167+
```
168+
169+
### Polyfill of map (Custom Implementation)
170+
```js
171+
// Over here calculate is nothing but polyfill of map function
172+
// console.log(radiusArr.map(area)) == console.log(calculate(radiusArr, area));
173+
174+
Array.prototype.calculate = function(operation) {
175+
const output = [];
176+
for (let i = 0; i < this.length; i++) {
177+
output.push(operation(this[i]));
178+
}
179+
return output;
180+
}
181+
console.log(radiusArr.calculate(area));
182+
```
183+
184+
## Summary
185+
Higher order functions are a key concept in JavaScript, enabling powerful patterns for abstraction, reusability, and functional programming.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Welcome to your comprehensive JavaScript interview notes! This repository contai
88
- [Functions](functions/functions.md)
99
- [Closures](Closures/closures.md)
1010
- [Event Loop](JS-Interview-Questions/eventloop.md)
11+
- [Higher Order Functions](JS-Interview-Questions/HigherOrderFunction.md)
1112
- [More Topics Coming Soon!]
1213

1314
---

index.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
# JavaScript Interview Notes: Index
1+
# JavaScript Concepts with Code Examples and Interview Questions:
2+
23

3-
Welcome! Use the links below to navigate the main topics:
44

55
- [Functions](functions/functions.md)
66
- [Closures](Closures/closures.md)
77
- [Event Loop](JS-Interview-Questions/eventloop.md)
8+
- [Higher Order Functions](JS-Interview-Questions/HigherOrderFunction.md)
9+
- [More Topics Coming Soon!]
810

911
---
1012

0 commit comments

Comments
 (0)