Call, Apply and Bind in JavaScript are very powerful function that allows you to borrow object properties and method. To understand this I am going to put a very simple example to output same result using all three function. (call, apply and bind). Let us look at the code below:-
let obj = {
num : 2
}
let addToThis = function(a, b, c){
return this.num + a + b + c;
}
In the above code we have an object with name obj
which has property called num
and its value is 2
. And another function with a name addToThis
which has parameter of a, b and c. It return the sum of a, b and c parameter along with property name called num
which is neither available in that function nor defined as global variable. num
is available in the global object named obj
. Now with the help of call
function we will try to access the property of obj
and perform the sum action and return the result.
console.log( addToThis.call(obj, 2, 3, 4) ); // output:- 11
--------------------------------
let obj = {
num : 10
}
function add(...args) {
let sum = 0 + this.num;
for(let i=0; i<args.length; i++) {
sum = sum + args[i];
}
return sum;
}
let num = [1,2,3,4,5];
console.log(add.apply(obj, num)) // 25
Real use case of Call function can be done in this way.
let car = function(wheels) {
this.wheels = wheels
}
let Maruti = function(wheels, isBS4Engine) {
car.call(this, wheels);
this.isBS4Engine = isBS4Engine;
}
let bmw = new Maruti(4, true)
console.log(bmw)
//output
{isBS4Engine: true, wheels: 4}
Let us suppose we have car constructor. A car may have 4 wheels in common. So I gave the property of wheels. We have one more constructor called Maruti which has wheels and engine type. In this constructor we have derived wheels property from car constructor and assign engine type. When the bmw car is created using Maruti constructor having wheels and isBS4Engine. Here’s another example of call.
let argsToArray = function(){
console.log(arguments);
console.log([].slice.call(arguments));
}
argsToArray(1,2,3)
Above code we have a function that no parameter defined. But while calling the function we pass 3 params. Now in order to access these 3 params we can use arguments
keyword of JavaScript. The only problem is that, it return those params as an array object with no Array prototype such as slice, push, splice etc. With this line of code [].slice.call(arguments)
we are trying to borrow all the prototype of an array (blank array still have array prototypes) to the arguments. Now when you console log it will return a perfect array.
Its same as Call but Apply accept function arguments as an array form. See the below example.
let arr = [2,3,4]
console.log(addToThis.apply(obj, arr)); // output:- 11
Real use case of Apply function
Math.min(1,2,3); //output : 1
In order to get minimum value out of the given parameter value we can use Math.min() method with split digits. Now using Apply function we can achieve same like this.
let num = [1,2,3]
let min = Math.min.apply(null, num);
console.log(min) // output: 1
JavaScript function becomes too complicated with this keyword when you have nested functions. Instead of borrowing obj the bind will get the entire object available for the local scope.
let obj = {
num : 2
}
let addToThis = function(a, b, c){
return this.num + a + b + c;
}
let bound = addToThis.bind(obj);
console.log(bound(2,3,4));
Real use case of bind can be done like this.
let app = {
getUser : function(cb){
cb();
},
parseUserData : function(){
console.log("Parse use");
},
renderGetUser : function(){
this.getUser(function(){
this.parseUserData();
}.bind(this))
}
}
app.renderGetUser()