Skip to content

Instantly share code, notes, and snippets.

@amandarfernandes
Last active December 13, 2017 10:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amandarfernandes/1394964f599ede786429fca9c3f71ab2 to your computer and use it in GitHub Desktop.
Save amandarfernandes/1394964f599ede786429fca9c3f71ab2 to your computer and use it in GitHub Desktop.
JSCallApplyBindExercise
<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
<div id="4">
</div>
<div id="5"></div>
/*
Write a function called arrayFrom which converts an array-like-object into an array.
Examples:
var divs = document.getElementsByTagName('div');
//divs.filter() // undefined
var converted = arrayFrom(divs);
console.log(converted.length)
converted.forEach(function(v) {console.log(v);}); // function(){}....
*/
function arrayFrom(arrayLikeObject){
return [].slice.call(arrayLikeObject);
}
/*
// Write a function called sumEvenArguments which takes all of the arguments passed to a function and returns the sum of the even ones.
Examples:
console.log(sumEvenArguments(1,2,3,4)) // 6
console.log(sumEvenArguments(1,8,6)) // 8
console.log(sumEvenArguments(1,2)) // 2
*/
function sumEvenArguments(){
var args = [].slice.call(arguments);
return args.reduce(function(accum,value,index){
return accum = ( index+1) % 2 === 0 ? accum+value: accum;
},0);
}
/*
Write a function called invokeMax which accepts a function and a maximum amount. invokeMax should return a function that when called increments a counter. If the counter is greater than the maximum amount, the inner function should return "Maxed Out"
Examples:
*/
function add(a,b){
return a+b
}
var addOnlyThreeTimes = invokeMax(add,3);
addOnlyThreeTimes(1,2) // 3
// addOnlyThreeTimes(2,2) // 4
// addOnlyThreeTimes(1,2) // 3
// addOnlyThreeTimes(1,2) // "Maxed Out!"
function invokeMax(fn, num){
var counter=0;
var maxedOut=false;
return function() {
if (!maxedOut) {
var nums = [].slice.call(arguments);
counter++;
if (counter >= num) {
maxedOut=true;
}
return fn.apply(this,nums);
} else {
return "Maxed Out";
}
};
}
/*
Write a function called once which accepts two parameters, a function and a value for the keyword 'this'. Once should return a new function that can only be invoked once, with the value of the keyword this in the function set to be the second parameter.
Examples:
function add(a,b){
return a+b
}
var addOnce = once(add, this);
addOnce(2,2) // 4
addOnce(2,2) // undefined
addOnce(2,2) // undefined
function doMath(a,b,c){
return this.firstName + " adds " + (a+b+c)
}
var instructor = {firstName: "Elie"}
var doMathOnce = once(doMath, instructor);
doMathOnce(1,2,3) // "Elie adds 6"
doMathOnce(1,2,3) // undefined
*/
function once(fn, thisArg){
var calledOnce=false;
return function() {
if (!calledOnce) {
calledOnce=true;
return fn.apply(thisArg, [].slice.call(arguments));
}
};
}
// BONUSES!
/*
Write a function called bind which accepts a function and a value for the keyword this. Bind should return a new function that when invoked, will invoke the function passed to bind with the correct value of the keyword this. HINT - if you pass more than two parameters to bind, those parameters should be included as parameters to the inner function when it is invoked. You will have to make use of closure!
Examples:
function firstNameFavoriteColor(favoriteColor){
return this.firstName + "'s favorite color is " + favoriteColor
}
var person = {
firstName: 'Elie'
}
var bindFn = bind(firstNameFavoriteColor, person);
bindFn('green') // "Elie's favorite color is green"
var bindFn2 = bind(firstNameFavoriteColor, person, 'blue');
bindFn2('green') // "Elie's favorite color is blue"
function addFourNumbers(a,b,c,d){
return a+b+c+d;
}
bind(addFourNumbers,this,1)(2,3,4) // 10
bind(addFourNumbers,this,1,2)(3,4) // 10
bind(addFourNumbers,this,1,2,3)(4) // 10
bind(addFourNumbers,this,1,2,3,4)() // 10
bind(addFourNumbers,this)(1,2,3,4) // 10
bind(addFourNumbers,this)(1,2,3,4,5,6,7,8,9,10) // 10
*/
function bind(fn, thisArg){
//console.log(arguments);
var args = [].slice.call(arguments,2);
return function() {
var fnArgs = args.concat([].slice.call(arguments));
return fn.apply(thisArg,fnArgs);
};
}
/*
Write a function called flip which accepts a function and a value for the keyword this. Flip should return a new function that when invoked, will invoke the function passed to flip with the correct value of the keyword this and all of the arguments passed to the function REVERSED. HINT - if you pass more than two parameters to flip, those parameters should be included as parameters to the inner function when it is invoked. You will have to make use of closure!
Examples:
function personSubtract(a,b,c){
return this.firstName + " subtracts " + (a-b-c);
}
var person = {
firstName: 'Elie'
}
var flipFn = flip(personSubtract, person);
flipFn(3,2,1) // "Elie subtracts -4"
var flipFn2 = flip(personSubtract, person, 5,6);
flipFn2(7,8). // "Elie subtracts -4"
function subtractFourNumbers(a,b,c,d){
return a-b-c-d;
}
flip(subtractFourNumbers,this,1)(2,3,4) // -2
flip(subtractFourNumbers,this,1,2)(3,4) // -2
flip(subtractFourNumbers,this,1,2,3)(4) // -2
flip(subtractFourNumbers,this,1,2,3,4)() // -2
flip(subtractFourNumbers,this)(1,2,3,4) // -2
flip(subtractFourNumbers,this,1,2,3)(4,5,6,7) // -2
flip(subtractFourNumbers,this)(1,2,3,4,5,6,7,8,9,10) // -2
flip(subtractFourNumbers,this,11,12,13,14,15)(1,2,3,4,5,6,7,8,9,10) // -22
*/
function flip(fn, thisArg){
var args = [].slice.call(arguments,2);
return function() {
var fnArgs = args.concat([].slice.call(arguments)).slice(0,fn.length);
return fn.apply(thisArg,fnArgs.reverse());
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment