Skip to content

Commit 225941c

Browse files
committed
higher order functions, closures, encapsulation
1 parent aee12fb commit 225941c

File tree

3 files changed

+158
-1
lines changed

3 files changed

+158
-1
lines changed

Assets/Closures.png

1.31 MB
Loading

Assets/HigherOrderFunc.png

1.43 MB
Loading

ClosuresPrototypalInheritance.md

Lines changed: 158 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,164 @@ function a() {
3131

3232
a()(); // => 'bye'
3333
```
34-
34+
---
3535
## Higher Order Functions
3636

37+
![Higher Order Functions](./Assets/HigherOrderFunc.png)
38+
3739
Higher order functions are simply functions that can take a function as an argument, or a function that returns another function.
40+
41+
<i>Example:</i>
42+
43+
```javascript
44+
const giveAccessTo = (name) => 'Access granted to ' + name
45+
46+
function authenticate(verify) {
47+
let array = [];
48+
for (let i = 0; i < verify; i++) {
49+
array.push(i);
50+
}
51+
return true;
52+
}
53+
54+
function letUser(user, fn) {
55+
if (user.level === 'admin') {
56+
fn(500000)
57+
} else if (user.level === 'general') {
58+
fn(100000)
59+
}
60+
return giveAccessTo(user.name);
61+
}
62+
63+
letUser({level: 'general', name: 'Corey'}, authenticate); // => "Access granted to Corey"
64+
```
65+
66+
<i>Example:</i>
67+
68+
```javascript
69+
const multiplyBy = (num1) => (num2) => num1 * num2
70+
71+
multiplyBy(5)(3); // => 15
72+
73+
const multiplyByTwo = multiplyBy(2);
74+
multiplyByTwo(5); // => 10
75+
```
76+
---
77+
## Closures
78+
79+
![Closures](./Assets/Closures.png)
80+
81+
We have these things called closures in JavaScript because of two things that we get. One is the fact that in JavaScript functions are a first class citizen, we can pass them around like data of any other type.
82+
83+
We also have this idea of lexical scope, that is the JavaScript engine knows based on where our code is written before we even run the code what variables each function has access to.
84+
85+
Closure is simply a combination of function and the lexical environment from which it was declared. Closures allow a function to access variables from an enclosing scope or environment even after it leaves the scope in which it was declared.
86+
87+
<i>Example:</i>
88+
89+
```javascript
90+
function a() {
91+
const grandpa = 'John'
92+
return function b() {
93+
const father = 'Simon'
94+
return function c() {
95+
const son = 'Luke'
96+
return `${grandpa} ${father} ${son}`
97+
}
98+
}
99+
}
100+
101+
a()()() // => "John Simon Luke"
102+
```
103+
104+
Closure is a feature of JavaScript where the JavaScript engine will make sure that the function has access to all of the variables contained in other functions in which it's nested in.
105+
106+
<i>Example using an arrow function:</i>
107+
108+
```javascript
109+
const family = (grandpa) => (father) => (son) => `${grandpa} ${father} ${son}`
110+
111+
family('John')('Simon')('Luke') // => "John Simon Luke"
112+
```
113+
114+
## Two main benefits of closures:
115+
116+
### 1. Memory efficiency
117+
118+
<i>Example without using a closure:</i>
119+
120+
```javascript
121+
function heavyDuty(index) {
122+
const bigArray = new Array(5000).fill('hi');
123+
console.log('func ran');
124+
return bigArray[index];
125+
}
126+
127+
heavyDuty(426);
128+
heavyDuty(2094);
129+
heavyDuty(3421);
130+
131+
// =>
132+
// func ran
133+
// func ran
134+
// func ran
135+
// hi
136+
```
137+
138+
<i>Same example but using a closure:</i>
139+
140+
```javascript
141+
function heavyDuty() {
142+
const bigArray = new Array(5000).fill('hi');
143+
console.log('func ran');
144+
return function(index) {
145+
return bigArray[index];
146+
}
147+
}
148+
149+
const getHeavyDuty = heavyDuty();
150+
151+
getHeavyDuty(745);
152+
getHeavyDuty(2734);
153+
getHeavyDuty(4711);
154+
155+
// =>
156+
// func ran
157+
// hi
158+
```
159+
160+
In the first example, `heavyDuty()` was created three times compared to the second example where by using closures `bigArray` was only created once because we knew we were going to access it a lot. We just maintained that closure scope over it and we were able to call it over and over without doing all that creation/destruction work from the memory heap.
161+
162+
### 2. Encapsulation
163+
164+
```javascript
165+
const makeNuclearButton = () => {
166+
167+
let timeWithoutDestruction = 0;
168+
const passTime = () => timeWithoutDestruction ++;
169+
const totalPeaceTime = () => timeWithoutDestruction;
170+
171+
const launch = () => {
172+
timeWithoutDestruction = -1;
173+
return 'kaboom';
174+
}
175+
176+
setInterval(passTime, 1000)
177+
178+
return {
179+
totalPeaceTime: totalPeaceTime
180+
}
181+
182+
}
183+
184+
const tryDetonate = makeNuclearButton();
185+
186+
tryDetonate.launch(); // => won't work, can't access due to encapsulation
187+
188+
tryDetonate.totalPeaceTime(); // => does work, will print elapsed time
189+
```
190+
191+
Data encapsulation in relation to closures refers to the idea of removing access to certain data which shouldn't be accessible to a user. In the example above the user is able to interact with the `totalPeaceTime` function but they can't access the `launch` function. This is because the `launch` function is not being returned in the scoped `makeNuclearButton` function.
192+
193+
194+

0 commit comments

Comments
 (0)