call, bind and apply for dummies
So I have been learning JavaScript from the past 8 months or so. One of the best approach to learn quickly is by building things. While building you come across a lot of different things which you probably won't be able to come across while your read stuff unless you are really good at doing Einstein's famous thought experiments. If that's the case, it was nice knowing and you can close this now.
If you fall in my category and many of my peers are in the same category. There's a good chance you didn't feel the need to use call, bind and apply methods (if you are still writing class based react components.. pls stop).
We have all heard the famous "Everything in JavaScript is an object", functions are no different. Every JavaScript function is actually an object, a Function object to be specific. But you would be like, wait a minute if function in JavaScript are objects then why don't we create it with a constructor and all that jazz. You can, there are three ways to define a function in JavaScript. Function constructor, function declaration and function expression. Here's how you would define a very difficult addTwoNumbers function in all the three ways.
Function() constructor
const addTwoNumbers = new Function('a', 'b', 'return a + b');
I know what you are thinking, function body as string. Yes. All the no semi-colon people, this is your nightmare. The thing to remember with functions created with Function constructor is it does not create closures to their creation contexts (maybe another blog for that, let me know)
Function expression
const addTwoNumbers = function (a,b) {return a + b}
Function declaration
function addTwoNumbers(a,b) {return a+b}
An object has methods and properties. Function being an object also has some. 4 methods to be precise. call, bind, apply and toString. The toString() method just returns the function source code represented in string. Now that toString is out of the way, we are left with three methods. call, bind and apply.
this
Before we dive into methods, it is important to get an understanding of the this
keyword. In layman's term, this
is a reference to an object. What this means in terms of call, bind and apply is this
will refer to the object which was passed.
call method
The call method invokes a function with a specified this
context, the arguments are provided individually if any. It calls a function with a given object as if the function is a method of the object.
const obj = {
num: 2
};
const addToThis = function(a, b) {
return this.num + a + b;
}
addToThis.call(obj, 2, 3);
// returns: 7
Let's recap on what is happening here. obj has only one property num
and no methods of itself. addToThis()
function takes two arguments a
, b
and returns the sum of a, b and num property of the referenced object. The referenced object above is obj
whose num property is 2, so the return value is 2 + 2 + 3 = 7.
apply method
It is exactly the same as call method the only difference is that call() accepts an argument list, while apply() accepts a single array of arguments.
const obj = {
num: 2
};
const addToThis = function(a, b) {
return this.num + a + b;
}
addToThis.apply(obj, [2,3]);
// returns: 7
Same thing as the call method, just the number of arguments are provided as an array instead of providing them individually.
bind method
bind is a little bit different than call and apply. Call and apply are one time methods. Bind glues together the function and the this
reference and returns the new function. So if you want to use a method over and over, bind is the way to go.
const obj = {
num: 2
};
const addToThis = function(a, b) {
return this.num + a + b;
}
const newFunction = addToThis.bind(obj, 2,3);
// return copy of the given function
// with the specified this value, and initial arguments
// obj and 2,3 in this case
newFunction();
// returns: 7
Now you can call the function newFunction() as many times as you want it will remember the reference to obj
, 2
and 3
.
That's it. I hope you have a better understanding of call, apply and bind method now.