JavaScript call bind and apply

javacript call bind and apply

Cinque Terre

As we can see the execution context in javacript which consists of memeory space holds all the variable, a special variable which points to a object outer reference known as this.

how nice it would be if we can control this variable ?

So, far we have seen javacript engine provides this vairable which refers to it's outer reference object. Now we will see how we can control this variable as per our need.

Let's start by seeing how a function is structured in javascript

Cinque Terre

So we can see function is nothing but a objecct which has Name which could be opitonal as we know function could be anonymus, it has code again a optional attribute as function could be just empty doing nothing. But it gets three method which are invocable bind, call and apply. One can call this three method an any javascript function-object.

javascript bind

var car = { make:'Honda', model:'civic', getCarDetails:function(){ return this.make + ' ' +this.model; } } var myCar = function(){ console.log(this.getCarDetails()); } myCar();
index.html:15 Uncaught TypeError: this.getCarDetails is not a function
Cinque Terre

wouldn't this be nice if we can control this ?

var car = { make:'Honda', model:'civic', getCarDetails:function(){ return this.make + ' ' +this.model; } } var myCar = function(){ console.log(this.getCarDetails()); }.bind(car); myCar();
Honda civic
As you can see we used bind to bind the car object with myCar object. So what happens when we use bind ? During bind function's this gets pointed to the binding object. In this case myCar's this now pointing to car object. And now it has access to the methd getCarDetails.

javascript call

call like bind gives opportunity to pass the this reference object and at the same it it invokes the function. var car = { make:'Honda', model:'civic', getCarDetails:function(){ return this.make + ' ' +this.model; } } var myCar = function(){ console.log(this.getCarDetails()); } myCar.call(car); // note it's passing the this object reference which is car and invoking myCar at the same time.
Honda civic

call allows you to pass parameter as well.

The first argument always this object reference and the rest follows by function arguments.

var car = { make:'Honda', model:'civic', getCarDetails:function(){ return this.make + ' ' +this.model; } } var myCar = function(color){ console.log('my '+this.getCarDetails()+' is '+color); } myCar.call(car,'red'); // note passing parameter along this
my Honda civic is red

javascript apply

apply does almost same what call does, only difference it passes all arguments in an array.

var car = { make:'Honda', model:'civic', getCarDetails:function(){ return this.make + ' ' +this.model; } } var myCar = function(color){ console.log('my '+this.getCarDetails()+' is '+color); } myCar.apply(car,['red']); // note passing parameter along this
my Honda civic is red

apply could be more handy than call as it allows to pass an array which could hold a list of values.
This gives flexibility on the number of arguments which is now encapsulated in an array.

where to use call, apply, bind

function borrowing is one of the situation where a object borrows a function from another object.
check this out.

function borrowing

var car = { make:'Honda', model:'civic', getCarDetails:function(){ return this.make + ' ' +this.model; } } var truck = { make:'HMV', model:'cargo', } console.log(car.getCarDetails.bind(truck))
HMV cargo

Did you see that ? object truck doesn't have the method getCarDetails, but now it's borrwing with the help of apply. We could have used call as well.

function currying

bind does rather more interesting, it could lock an argument value and then make the function behave more precsie way. function addByTwo(b){ var a = 2; return a + b; } console.log(addByTwo(3));
5
The above example simple enough to understand.
Let's do it little differently and see how bind can help us to achive the same. function add(a,b){ return a + b; } var addByTwo = add.bind(this,2); var addByFive = add.bind(this,5); var addByNine = add.bind(this,9); console.log(addByTwo(3)); console.log(addByFive(3)); console.log(addByNine(3));
5
8
12

Quite clearly we can see along with bind and defining argument value we can create specific functions out of a genecric function.
This feature could be very helpful while creating javascript library (we will see that in future).

Back Next