Skip to content

Instantly share code, notes, and snippets.

@gsoldateli
Created October 3, 2017 13:19
Show Gist options
  • Select an option

  • Save gsoldateli/043d642811bab129a50485b97ce1e534 to your computer and use it in GitHub Desktop.

Select an option

Save gsoldateli/043d642811bab129a50485b97ce1e534 to your computer and use it in GitHub Desktop.

Describe how the JavaScript built-in functions apply and call work. Use examples to demonstrate how each one works.

Setting The Context of a JavaScript Function

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.

Excuse me, can you lend me this function?

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.

Good story, but this Richard... He doesn't use the eraser at its full potential!

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!"

Live Example

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:

  • apply requires an array. schoolMate.erase.apply(me,[true]);. Do you see? [true] is inside an array.
  • call accepts the arguments outside an array. schoolMate.erase.apply(me,true);.

Okay, this eraser thing is so silly. Show some real code please?

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"

Live Example

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment