Understanding .bind(), .call(), and .apply()
As an amatuer javaScripter, I had quite a bit of trouble fully understanding how .bind, .call, and .apply was used.
I’ve since started the Hack Reactor program and had quite a nice ‘a ha!’ moment while listening to a lecture on this subject.
First off, it’s important to understand that all three methods perform ONE similar action. This action is they all define what object the keyword ‘this’ is going to mean. Here is some simple code:
____________________________________
var helloObject = { hello: ‘hello’ };
var helloWorld = function () {
return this.hello + ‘ world!’;
};
helloWorld();
____________________________________
Because the helloWorld function is defined in the global object, the ‘this’ keyword is going to refer to the global object. Since there’s no ‘hello’ variable created on the global object (which would create Window.hello), ‘this.hello’ is undefined. This causes the helloWorld invocation completely pointless.
So, how can .bind, .call and .apply handle this situation?
____________________________________
var helloObject = { hello: ‘hello’ };
var helloWorld = function () {
return this.hello + ‘ world!’;
};
var newFunction = helloWorld.bind(helloObject);
newFunction();
____________________________________
Notice that I created a new variable named ‘newFunction’. That wording is key to this aspect of .bind because the .bind method actually CREATES and NEW function with the ‘this’ keyword now pointing to whatever object you’ve passed in. Essentially, you’re saying this:
____________________________________
var newFunction = function () {
return helloObject.hello + ‘world!’;
};
____________________________________
That .bind creates a NEW function is key to understanding the difference between .bind and .call, and the difference between .bind and .apply. Therefore, once you’ve used .bind, you must invoke your new function, hence “newFunction()” above.
Let’s take the same code but refactor it using .call:
____________________________________
var helloObject = { hello: ‘hello’ };
var helloWorld = function () {
return this.hello + ‘ world!’;
};
helloWorld.call(helloObject);
____________________________________
Notice here, I didn’t create the variable newFunction. This is because .call not only establishes what object ‘this’ is referring to, but .call also CALLS the function. The .call method as used above is really saying:
____________________________________
helloWorld = function () {
return helloObject.hello + ‘ world!’;
};
helloWorld();
____________________________________
Or, written as an IIFE (immediately invoked function execution):
____________________________________
(function helloWorld () {
return helloObject.hello + ‘ world!’;
}()
____________________________________
That .call immediately calls the function is exactly how .appy acts as well.
Hopefully by now, you understand what these methods do with regards to the ‘this’ keyword. And you understand the difference between the .bind method and the .call and .apply method in function invocation.
But, what’s the difference between .call and .apply then? The ONLY difference is how arguments are passed into your function. Examine the following code:
____________________________________
var helloObject = { hello: ‘hello’ };
var helloWorld = function (word) {
return this.hello + word +‘ world!’;
};
helloWorld.call(helloObject, ‘crazy’);
____________________________________
As you can see, .call accepted ONE argument. This is different than .apply in that .apply can accept an ARRAY of arguments:
____________________________________
var helloObject = { hello: ‘hello’ };
var helloWorld = function (word1, word2, word3) {
return this.hello + word1 + word2 + word3 +‘ world!’;
};
helloWorld.apply(helloObject, [‘ crazy’, ‘ wild’, ‘ fun’]);
____________________________________
I’ll let you experiment on how .bind passes in arguments.
I hope this helps. As a follow up to this, be sure to read my next post, What the Hell is Currying?