Monday, February 23, 2015

JavaScript difference between bind() VS call() and apply()

First of all let me discuss about the keyword this in JavaScript.
this always refers to the “owner” of the function we're executing, or rather, to the object that a function is a method of. So e.g. create an object called obj like this:
var obj = {
    x: 81,
    getX: function() {
        console.log(this.x);
        return this.x;
    }
};
obj.getX(); //81
Here the this keyword refers to the object (obj) itself because we are going to call this function from the object's context. A golden rule here is to look at who called the function. Another example could be a global function:
function globalFunction() {
    console.log(this);
}
This can be confusing, because a man could think 'so who is calling this function? Who is the owner?
Well, JavaScript has a bad habit of dealing with variables: the function will be assigned to the global variable, in a browser it is the window object. So right now these two calls are equivalent:
globalFunction();
window.globalFunction();
Therefore in the function globalFunction, this will refer to the global window object.
Now let's move on to the next step to understand the functions bind, call and apply.
With these functions we can manipulate the keyword this in a function. Very interesting, and indeed, we do need these kind of functions. Why? E.g. jQuery's forEach call on a set of HTML elements would be very funny to use if the keyword this would not be the element of the iteration, isn't it? So the implementation includes the the function call to make sure, this is referred to the variable of the iteration.
But let's take a look back to our example. How can we force obj 's getX function to reference the this keyword to a variable we want to give? The solution is what (hopefully) you think: call, apply and bind functions. Let's see on examples, what is happening with each cases:
var otherObj = {
    x: 99
};
obj.getX.call(otherObj); //99
obj.getX.apply(otherObj); //99
var myGetXFunction = obj.getX.bind(otherObj); //returns a function
myGetXFunction(); //99
What is happening here? call will manipulate the this keyword to our variable in the first argument inside the function. The only difference between call and apply is apply lets you invoke the function with arguments as an array; call requires the parameters be listed explicitly.
However, bind will not execute the function. bind will only give a reference to a function, which is similar to the original function, but the keyword this is changed to our variable. Very elegant!
I hope you understand now more the meaning and reason behind these functions.
A JSFiddle example is below: