You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- You can return functions as values from other functions.
@@ -29,7 +29,7 @@ function a() {
29
29
};
30
30
}
31
31
32
-
a()(); //=> 'bye'
32
+
a()(); //-> 'bye'
33
33
```
34
34
---
35
35
## Higher Order Functions
@@ -60,22 +60,24 @@ function letUser(user, fn) {
60
60
returngiveAccessTo(user.name);
61
61
}
62
62
63
-
letUser({level:'general', name:'Corey'}, authenticate); //=> "Access granted to Corey"
63
+
letUser({level:'general', name:'Corey'}, authenticate); //-> "Access granted to Corey"
64
64
```
65
65
66
66
<i>Example:</i>
67
67
68
68
```javascript
69
69
constmultiplyBy= (num1) => (num2) => num1 * num2
70
70
71
-
multiplyBy(5)(3); //=> 15
71
+
multiplyBy(5)(3); //-> 15
72
72
73
73
constmultiplyByTwo=multiplyBy(2);
74
-
multiplyByTwo(5); //=> 10
74
+
multiplyByTwo(5); //-> 10
75
75
```
76
76
---
77
77
## Closures
78
78
79
+
Closures allow a function to access variables from an enclosing scope or outer scope environment even after it leaves the scope in which it was declared because all that matters in Javascript is where the function was written.
80
+
79
81

80
82
81
83
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.
@@ -98,7 +100,7 @@ function a() {
98
100
}
99
101
}
100
102
101
-
a()()() //=> "John Simon Luke"
103
+
a()()() //-> "John Simon Luke"
102
104
```
103
105
104
106
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.
@@ -108,7 +110,7 @@ Closure is a feature of JavaScript where the JavaScript engine will make sure th
tryDetonate.launch(); //=> won't work, can't access due to encapsulation
188
+
tryDetonate.launch(); //-> won't work, can't access due to encapsulation
187
189
188
-
tryDetonate.totalPeaceTime(); //=> does work, will print elapsed time
190
+
tryDetonate.totalPeaceTime(); //-> does work, will print elapsed time
189
191
```
190
192
191
193
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
194
195
+
<br>
196
+
197
+
---
198
+
## Prototypal Inheritance
199
+
200
+
Inheritance is when an object gets access to the properties and methods of another object.
201
+
202
+
#### Why is prototypal inheritance useful?
203
+
204
+
The fact that objects can share prototypes means that you can have objects with properties that are pointing to the same place in memory without the need to repeat code, thus being more efficient.
The chains in this diagram represent prototypal inheritance. Arrays and functions in JavaScript get access to the methods and properties of objects.
209
+
210
+

211
+
212
+
Here we created an array, and by appending `.__proto__` we can go up the prototype chain and view the array constructor.
213
+
214
+

193
215
216
+
By appending another `.__proto__` we can go up the chain another level and view the object constructor.
217
+
218
+
---
219
+
<br>
220
+
221
+
### Manually creating a prototype chain
222
+
223
+
#### Note: You should never use `__proto__` to manually assign the prototype chain yourself (like in this example). It will conflict with the compiler and cause performance issues. The purpose of this is to simply explain how it works.
224
+
225
+
<i>Example:</i>
226
+
227
+
```javascript
228
+
let dragon = {
229
+
name:'Fred',
230
+
fire:true,
231
+
fight() {
232
+
return5
233
+
},
234
+
roar(){
235
+
if (this.fire) {
236
+
return`I am ${this.name}, the breather of fire.`
237
+
}
238
+
}
239
+
}
240
+
241
+
let lizard = {
242
+
name:'Larry',
243
+
fight() {
244
+
return1
245
+
}
246
+
}
247
+
248
+
lizard.__proto__= dragon;
249
+
250
+
lizard.roar() // -> "I am Larry, the breather of fire"
251
+
lizard.fire// -> true
252
+
lizard.fight() // -> 1
253
+
254
+
dragon.isPrototypeOf(lizard) // -> true
255
+
```
256
+
257
+
Here lizard is inheriting all the properties and methods of dragon through a prototype chain and is then overriding some attributes in it's own object declaration.
258
+
259
+
```javascript
260
+
for (let prop in lizard) {
261
+
console.log(prop) // -> name, fight, fire, roar
262
+
}
263
+
```
264
+
265
+
Here we're looping through all of lizard's properties and logging them out.
266
+
267
+
```javascript
268
+
for (let prop in lizard) {
269
+
if (lizard.hasOwnProperty(prop)) {
270
+
console.log(prop) // -> name, fight
271
+
}
272
+
}
273
+
```
274
+
275
+
Here we're looping through all of lizard's properties, filtering them with the `hasOwnProperty()` method and logging out only it's own (non-inherited) properties.
276
+
277
+
---
278
+
<br>
279
+
280
+
### Inheritance using `Object.create()`
281
+
282
+
<i>Example:</i>
283
+
284
+
```javascript
285
+
let iphone11 = {
286
+
wirelessCharging:true
287
+
}
288
+
289
+
let iphone11Pro =Object.create(iphone11)
290
+
291
+
iphone11Pro.wirelessCharging// -> true
292
+
```
293
+
294
+
Here we're creating inheritance using `Object.create()`
Every function has a prototype property and it references to an object used to attach properties that will be inherited by objects further down the prototype chain.
304
+
305
+
The last object in the chain is this built in `Object.prototype`.
`Object` is a function because it has the prototype property. The `Object.prototype` is what we call the base object. That's the very last piece or the very last object that we can look for properties on before we point to null.
310
+
311
+
---
312
+
<br>
313
+
314
+
### Exercise:
315
+
#### Extend the functionality of the built-in `Date` object by creating your own method which prints the previous year of a given date.
316
+
317
+

318
+
319
+
These are all the built-in methods we can use with the `Date` object.
Now if we run `Date.prototype` we see our new function appears in the list of methods.
334
+
335
+
---
336
+
<br>
337
+
338
+
339
+
### Exercise:
340
+
#### Extend the functionality of the built-in `Array` object by creating your own method which appends an exclamation mark to each value of an array.
341
+
342
+
<i>Solution:</i>
343
+
344
+
```javascript
345
+
Array.prototype.emphasise=function() {
346
+
let arr = [];
347
+
for( let i =0; i <this.length; i++ ) {
348
+
arr.push((this[i] +'!'))
349
+
}
350
+
return arr
351
+
}
352
+
353
+
[1,2,3].emphasise() // -> ["1!", "2!", "3!"]
354
+
```
194
355
356
+
<i>Note: You can't use arrow functions in these solutions because the value of `this` would be lexically scoped to point to the function itself. We need to use a function expression because we want the value of `this` instead to be determined at call time when we actually run the function.</i>
0 commit comments