UI Development

Understanding Apply, Call, and Bind

Working with “this” keyword can be tricky and confusing when compared to other programming languages when compared to that in JavaScript. The present object can always be referred with “this”, how the function is being called will change the value of “this”. Let’s take a real-time example there is a family with husband-wife and two kids, and they live inside a house and the house address XYZ drive. The wife said to the husband that we need to renovate this house because this house is falling apart. If we the above scenario the wife says an interesting word this house but she does not say the house on XYZ drive is falling apart i.e. is because we are inside the house so you can refer it as this. Let’s say there is a table in the house we can refer to it as this table. This keyword means the same thing if you are in a specific scope or object or function this means you are in whichever object you are in.

this.table= "Window Table";	
	this.garage={
		table: "Garage table",
		cleanTable(){
		 	console.log('cleaning '+this.table+'');
		}
	};
	 
	let sachinRoom ={
		table: "Sachins Table",
		cleanTable(){
		 	console.log('cleaning '+this.table+'');
		}
	};
	console.log(this.table);
	sachinRoom.cleanTable();
	this.garage.cleanTable();

From the above example, we can get a clear idea of “this”. The “this.table” inline 1 this here is in global scope which means we are in a window scope and we do the console log of this we will get “Window Table”. In line 2 “this.garage” is a global object and has a table if we want to access the table we can call it by “this.garage.table” or we can also call “window.garage.table”. Inline no 9 we have created a private object and suppose we want to access the table inside Sachin room then when we try with “this.sachinRoom.table” this then it will cause an error because it’s a private variable so we need to use “sachinRoom.table”. Now let us see how this works with methods for eg when we call the clean table in Sachin room this scope in the clean table is limited to the sachinRoom object we can call it by “sachinRoom.cleanTable()” but if we need to use the clean the table in the garage then we need to use “this.garage.cleanTable()” here the cleanTable is a method of Sachin room similarly for the garage. I hope u all a better understating of “this” keyword and scope of this in global and private objects.

Now let’s start to understand how call, apply and bind work in JavaScript. Use of call, apply or bind you can explicitly determine what this should refer to how a function is called. call() and apply() were introduced in ECMAScript3 whereas bind was added in ECMAScript5.

USES

Call and apply are used to invoke the function immediately. Bind returns abound to the function which can be executed later, will have “this” context for calling the function .so bind can be used later when a certain event requires the function.

Call & Apply Method:

Let’s look at originally what a call and Apply definition given by MDN.

call() & apply() are very similar which invoke a function with a specific this context along with addition/optional arguments. The major difference between call and apply is that in call the arguments are to be passed one by one whereas in apply takes arguments as an array or array-like objects which may refer to Node List or the arguments object inside a function.

Call() Example:

 let add = function(c){
	  console.log(this.a + this.b + c );
	};
	 
	let obj= {
	  a: 1 ,
	  b: 2
	};
	 
	add.call(obj, 3);

In the above example, we have a function “add” which takes one argument c and it logs the sum of a b c values .then we have an object and which has two properties a & b with values assigned to them and we make a call to add where we pass the obj and c value as we can pass a parameter in add function. When we run this function, we will get 6 as you see we have used add function which is not a part of obj but we can use it with the help of call function.

let mammals=function(legs){
	  this.legs=legs;
	};
	 
	let cat=function(legs,isDomesticated){
	  mammals.call(this,legs);
	  this.isDomsticated=isDomesticated;
	};
	 
	let lion =new cat(4,false);
	console.log(lion);

Similar to the previous example we have another example where mammals is a base constructor that has a function with legs as a property where legs are assigned to “this.legs”.In order to define the mammal is domestic or not we can use this.legs which is a sub constructor of the cat which is a part if the mammals. The no of legs will be called by call() of mammals. Now we have a cat if we want lion, we have this constructor of lion which is equal to the new cat and we can give parameters to it. Then we console log lion and run it we get legs equal to 4 and is Domesticated is equal to false.

Apply() Example:

let numArray =[1,2,3];
console.log(Math.min.apply(null,numArray));

Apply is similar to call() but we need to send the arguments as an array in the above example we are sending the array of numbers using numArray this returns the min value in the array using math function.

Bind Method:

Lets us again start with looking at the MDN definition

 

 

 

 

 

 

 

 

 

 

The bind function is much like the call function, the main difference is that bind and return a new function whereas call does not.

According to ECMAScript 5 the function returned by bind is a special type of exotic function object called the Bound function (BF). The BF wraps the original function object. Calling the BF runs the wrapped function in it.

Example:

        let button= function(content){
	  this.content=content;
	};	 

	button.prototype.click=function(){
	  console.log(this.content+" clicked");
	};
	 
	let newButton=new button('add');
	 
	let boundButton = newButton.click.bind(newButton);
	 
	boundButton();

In the above example we button equal to function which as content as a parameter and inside it this.content is equal to content and we creating a click event inline 5  which will console the content. let us create newButton because the button is a constructor and we are passing a parameter add and this function is loosely bound to newButton we can verify it by  “let looseClick =newButton.click” if we add this instead of line 11 and we call we will get undefined so we use bind() to make it bound using the boundButton we can now bind back to the object which was loosely bound. And now if we run this now we will get “add clicked”.

	let myObj ={  
	asyncGet(cb){
	    cb();
	  },
	  parse(){
	    console.log('parse called');
	  },
	  render(){
	    this.asyncGet(function(){
	      this.parse();
	    
	    }.bind(this));
	    
	  }
	};
	
    myObj.render();

 

Another application of bind like the code above. We have created an object called myobj which is an object literal inside we have a method called async and this will get some value synchronously when its called and we call another property parse which will return which all data it gets back and we can pass it into the syncget and it also has a button render and this method would call asyncGet and which would call parse. we are passing the scope of this for parse using bind which means we are binding the outer this to the inner this. When we run this we get ‘parse called’ in console.

The major differences between the bind() and call() method are:

Executes the function right away when its called.
Accepts additional parameters as well.
The call() method does not require a copy of the function.

About The Author