Skip to content

Instantly share code, notes, and snippets.

@FaisalAl-Tameemi
Last active October 6, 2016 21:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save FaisalAl-Tameemi/c660f9ea8b4d19c06a5257d7f34726a4 to your computer and use it in GitHub Desktop.
Save FaisalAl-Tameemi/c660f9ea8b4d19c06a5257d7f34726a4 to your computer and use it in GitHub Desktop.
Callbacks / Higher Order Functions Examples.
/**********************************************************************
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.
'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`);
});
'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;
'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);

Callbacks

To Discuss:

  • 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment