- Functions are values
- What are anonymous functions? (example)
- Function declaration vs function expression
- Function calling vs passing (reference to a function)
- Callback functions and Higher order functions
- Implementing our own
.map
function
Last active
October 6, 2016 21:38
-
-
Save FaisalAl-Tameemi/c660f9ea8b4d19c06a5257d7f34726a4 to your computer and use it in GitHub Desktop.
Callbacks / Higher Order Functions Examples.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************************************************** | |
Example 1: we can store a function like we store any other value. | |
In the example below, the function we are storing in `sumArray` is actually unnamed | |
which is to say it's an "annonymous" function. | |
**********************************************************************/ | |
var sumArray = function(arr){ | |
return arr.reduce(function(sum, elm){ | |
return sum += elm; | |
}, 0); | |
} | |
var total = sumArray([44, 22, 12, 10]); | |
debugger; | |
/********************************************************************** | |
Example 2: We can also assign the value of `sumArray` to a function | |
with the name `sunFunc` | |
**********************************************************************/ | |
var sumArray = function sumFunc(arr){ | |
return arr.reduce(function(sum, elm){ | |
return sum += elm; | |
}, 0); | |
} | |
var total = sumArray([44, 22, 12, 10]); | |
debugger; | |
/********************************************************************** | |
In the 2 examples above, we assigned a function to a variable. This is called | |
"function expression". | |
Example 3: we use "function declaration" below were we declar a function `sumArray`. | |
While the final value of the `total` variable will remain the same, a few things are happening | |
differently. | |
**********************************************************************/ | |
// Using a function before its declaration is called function 'hoisting'. | |
// It's useful when you have multiple scripts running at once but can | |
// create bugs that are hard to track. | |
var total = sumArray([44, 22, 12, 10]); | |
function sumArray(arr){ | |
return arr.reduce(function(sum, elm){ | |
return sum += elm; | |
}, 0); | |
} | |
debugger; | |
/********************************************************************** | |
QUESTION 1: what's the output of `my_var` below? | |
**********************************************************************/ | |
function getValue() { | |
return 44; | |
} | |
var my_var = getValue(); | |
function getValue() { | |
return 88; | |
} | |
debugger; | |
/********************************************************************** | |
QUESTION 2: what's the output of `my_var` below? | |
**********************************************************************/ | |
var getValue = function() { | |
return 44; | |
} | |
var my_var = getValue(); | |
var getValue = function() { | |
return 88; | |
} | |
debugger; | |
/********************************************************************** | |
QUESTION 3: what's the output of `my_var` below? | |
**********************************************************************/ | |
var my_var = getValue(); | |
var getValue = function() { | |
return 44; | |
} | |
var getValue = function() { | |
return 88; | |
} | |
debugger; | |
// [Discuss] this is why its generally better practice to use function expression. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/* | |
In this example, we will pass a callback to a `countDown` function | |
which will get called (aka "invoked") when the countdown is done. | |
*/ | |
/** | |
@description: counts down from `num` to 0 and prints each number | |
then invokes the callback function if provided | |
@params: `num`: Integer, | |
`_done`: (callback) Function | |
*/ | |
const countDown = function(num, _done){ | |
// measure when the loop started | |
const start = new Date().getTime(); | |
let count = 0; | |
for(let i = num; i >= 0; i--){ | |
console.log(i); | |
} | |
// measure when the loop was done | |
const end = new Date().getTime(); | |
// invoke the callback with the time diff | |
return _done(num, end - start); | |
} | |
// Test the `countDown` function | |
countDown(80, function(n, time_diff){ | |
console.log(`Counting to ${n} took ${time_diff} ms`); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/* | |
Since functions are treated like all other first class objects in JS. | |
This allows us to pass functions to other functions. We have previously | |
called this a callback (or a "higher order function"). | |
By that principle, we should be able to return functions as the response | |
for another function. We can refer to functions that return other functions | |
as generators. | |
*/ | |
const generateMapFunc = function(type){ | |
switch(type){ | |
case 'double': | |
return function(num){ return 2 * num; } | |
case 'square': | |
// or return an annonymous function | |
return function(num){ return num * num; } | |
default: | |
// unknown case, ~ else | |
break; | |
} | |
} | |
var doubled_vals = [1, 2, 3, 4].map(generateMapFunc('double')); | |
var squared_vals = [1, 2, 3, 4].map(generateMapFunc('square')); | |
debugger; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/* | |
In this example, we will implement our own `.map` function to get a better | |
understanding of how callbacks and invoked. | |
Keep in mind that callbacks can be invoked multiple times by a function, | |
unlike how we used it in the previous example. A good use case of this is how | |
functions such as `.forEach` or `.map` invoke the callback multiple times. | |
Unlike the normal `.map` function that JS provides for us out of the box, | |
our function will have to the an array as a parameter as well. | |
*/ | |
/** | |
@description: transforms all array elements into a new array of equal size | |
using the provided callback. | |
@params: `elements` => the array to map | |
`_mapElement` => the callback function to transform an element | |
*/ | |
const map = function(elements, _mapElement){ | |
// check if the elements variable is actually an array | |
// if(!typeof elements === 'Array'){ return; } | |
const mapped_elements = []; // init an empty list to store new mapped values in | |
// for each element in the provided array | |
for(let i = 0; i < elements.length; i++){ | |
const current_elm = elements[i]; | |
const new_element = _mapElement(current_elm); | |
mapped_elements.push(new_element); | |
} | |
// respond with the final mapped set of elements | |
return mapped_elements; | |
} | |
// Test the map function above | |
const squared = map([1, 2, 3], function(current){ | |
return current * current; | |
}); | |
console.log('Expected: [1, 4, 9], Got:', squared); | |
// Another test | |
const people = [{ | |
name: 'John Doe', | |
age: 23 | |
}, { | |
name: 'Jane Doe', | |
age: 26 | |
}]; | |
const first_names = map(people, function(person){ | |
// return the first name only | |
return person.name.split(' ')[0]; | |
}); | |
console.log('Expected: ["John", "Jane"], Got:', first_names); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment