`this` in JavaScript functions
I recently read Secrets of the JavaScript Ninja and found it to be quite good. It should be helpful to anyone who knows JavaScript but has fragmented understanding of concepts.
For example, I have learned most of the concepts in JavaScript when I have hit a roadblock in implementation or found a bug and read a few StackOverflow answers or blog posts about the issue.
With more than five years of experience programming in JavaScript, it is not small, but some concepts still were not as clear as they became after reading that book.
One such concept is functions and this
keyword. My basic understanding was that it is quite simple, like in Java, i.e., this represents the object where that function is defined, otherwise it represents global scope.
Again, the above concepts are simple, and we know what will happen, but there is one single most important thing I didn’t understand as clearly as I should have, that the value of this
does not depend on where that function is defined, but the way it is called.
Most of you know we can change it with apply and call by passing appropriate parameters, but even in normal calls, there is a convention with respect to this value.
function topLevel(){
// Noramlly, here this would be window
console.log(this);
}
var obj = {
fn: function(){
// Noramlly, here this would be obj
console.log(this);
}
};
topLevel();
obj.fn();
// different way to call obj.fn
var objfn = obj.fn;
// here this keyword will be window i.e. global scope
// since we are calling it directly instead of in <Object>.<function> notation
objfn();
// there are some obvious other ways to achieve same effect
objfn.call(obj);
// or
objfn.apply(obj);
The above code shows how the value of this
changes when we call the same function in a different way.
There is one more thing related to constructor functions that we call like this.
var tree = new Tree();
Although it is not at all equivalent, it is conceptually similar to this.
var tree = Tree.call({});
That is basically, new Tree() calls Tree constructor with this set to blank and returns it as a new object after initialization in constructor function.