Describe how the JavaScript built-in functions apply and call work. Use examples to demonstrate how each one works.
Category: Working with The JavaScript this Keyword.
apply and call methods were developed to give you more flexibility in your code avoiding writing duplicated functions. This reason per se is strong enough to read this article or any other on the subject.
Have you ever borrowed an eraser from a schoolmate in order to have the ability to erase something?
You use your mouth to ask for an eraser, javascript functions use apply and call.
//This is you. And you forgot your eraser.
var me = {name:"John"};
//This is Richard, your schoolmate, he brought his eraser.
var schoolMate = {
name: "Richard",
erase: function(){ //This function is Richard's eraser.
console.log("This is an eraser used by "+ this.name);
}
};
//Here you notice that Richard is erasing something. And you want to erase something too.
schoolMate.erase(); //Outputs: "This is an eraser used by Richard"
//Then you ask him "Can you borrow me your eraser Richard?"
schoolMate.erase.apply(me); //Outputs: "This is an eraser used by John."Could you see what happened in the code above?
schoolMate.erase.apply(me) set the erase method this from schoolMate the me object.
So, this.name will be John. Resulting in the output: This is an eraser used by John instead This is an eraser used by Richard.
You notice that you can erase way better than Richard just by putting an extra effort in your hand while erasing.
Just by passing an extra parameter to the borrowed function as showed below:
//This is you. And you forgot your eraser.
var me = {name:"John"};
//This is Richard, your schoolmate, he brought his eraser.
var schoolMate = {
name: "Richard",
erase: function(){ //This function is Richard's eraser.
var extraEffort = arguments[0]; //Javascript default extra argument list
console.log("This is an eraser used by "+ this.name);
if(extraEffort) {
console.log("And well used!");
}
else {
console.log("But without effort.");
}
}
};
//Here you notice that Richard is erasing something. And you want to erase something too.
schoolMate.erase(); //Outputs: "This is an eraser used by Richard" "But without effort."
console.log('-------------');
//Then you ask him "Can you borrow me your eraser Richard?"
schoolMate.erase.apply(me,[true]); //Outputs: "This is an eraser used by John." "And well used!"
//When you use call, the function is borrowed in the same way as apply.
//The only difference is the way you pass extra arguments:
//
//---> apply accepts an array as extra argument.
//---> while call accepts the arguments without putting them inside an array.
schoolMate.erase.call(me,true); //Also outputs: "This is an eraser used by John." "And well used!"You can ask for an eraser in so many ways such as:
Do you mind lending me your eraser ?
Can I borrow your eraser?
In both ways you'll get the eraser.
Javascript have the apply and call.
The only difference between the two is the way the arguments are passed to the borrowed function:
applyrequires an array.schoolMate.erase.apply(me,[true]);. Do you see?[true]is inside an array.callaccepts the arguments outside an array.schoolMate.erase.apply(me,true);.
I hope that the story above helped you to at least fix the strategic value of apply and call functions.
Now real code:
//removeSymbols is a function that removes any symbols from an input.
function removeSymbols(input) {
//>>>> IMPORTANT: [].map.call borrows the array map function to the input variable.
return [].map.call(input,function(char){
//Get the char code
charCode = char.charCodeAt(0);
//Only return the charCode if it ranges from a-z|A-Z|0-9|(whitespace)
return ( (charCode >= 65 && charCode <= 90) || (charCode >= 97 && charCode <= 122) || (charCode >= 48 && charCode <= 57) || charCode == 32 )? char :'';
}).join(''); //Join the proccessed array and returns it.
};
console.log(removeSymbols("!$%#TEXT$%# TEXT2@")); //Function removes all symbols outputting: "TEXT TEXT2"This statement [].map.call(input,function(char){/* ... */}); borrows the array's map function to the string input variable resulting in a cleaner code.
You simply do not need to recreate the map function or write some more complex loop to weed out the symbols from the string.
Guilherme Soldateli
10/03/2017
Career Path 3: Modern Frontend Developer