JavaScript has call, apply and bind methods. These are very powerful and useful methods. But before we know about those functions we need to understand function, scope, and context.
In javascript, we have two ways to create a function or method.
// function by declaration.
function msg () {}
// function by expression.
var msg = function () {};
But the interesting thing is we have 3 ways to invoke or call to function:
// Normal invoke
function msg () {}
msg()
// Self invoke
(function msg() {}());
// apply, call, bind
msg.apply();
msg.call();
msg.bind()();
Now comes to the point using the call, apply and bind method, we can call any function and apart from that we can manipulate the context of that function. Now the question arises in our mind what is the context? So basically context is just a current this.
Let’s take an example to understand this:
function msg() { return this; }
msg(); // return window object
var student = { name: "xyz" };
msg.call(student); // return student obj
Here apply and call methods are the same but the basic difference is that apply method requires an array as the second parameter but call parameters to require a separate one.
The first parameter is the value this provided for the invoke to function(msg).
Let’s take an example –
var math = {
setNo: function (a, b) {
this.a = a;
this.b = b;
}
add: function () {
return this.a + this.b;
}
};
function sum (){
return this.a + this.b;
}
math.setNo(2, 3);
math.add(); // 5
sum.call(math); // 5
sum.apply(math); // 5
sum.bind(math)(); // 5
Here sum is different but it’s using math object value;
If you don’t need to manipulate context then you just pass a null value;
function add (a, b) { return a + b; }
add.apply(null, [2, 3]); // 2, 3 in array
add.call(null, 2, 3); // 2, 3 are separate parameters
Here the first parameter is required otherwise your value is taken as this or context.
But the bind case little different here first set this then it returns this set function after that call or invokes.
var sum = add.bind(null, 2, 3);
sum(); // 5
Basic use case example –
Find max and min
Math.min.apply(null, [6, 5, 4]); // 4
Math.max.apply(null, [6, 5, 4]); // 6
Math.max.call(null, 6, 5, 4); // 6
Math.min.bind(null, 5, 7, 8); // 5
Flat push in arrays
var arr = [2, 3, 4];
array.push.apply(arr, [ 1, 2]); // 2, 3, 4, 1, 2
Losing this
var stu = {
name: "xyz",
getName: function () { alert("My name is " + this.name); }
};
// In normal case
setTimeout(stu.getName, 100); // My name is
// Using bind
setTimeout(stu.getName.bind(stu), 100); // My name is xyz
Here, In a normal case, we lose current this or context because; as you know in the browser API; the window object is our current this or context; So in that kind of situation bind, apply and call method can be useful.