Solving the Intricacies of the “this” keyword in Javascript

So I’ve decided to do “mini” posts on certain topics that have always consumed me in my daily development tasks. And as many of you may know, Javascript is a language that is a bit more challenging to master.

JavaScript

It’s such an expressive language that there are so many ways to accomplish things. One of them is using the “this” keyword in your programs.

Check the “Call Site”

This is the first thing you need to do to find what the “this” keyword contains. I know you can simply do a “console.log(this)” from inside your functions, but the mystery is “how it got that value” in the first place. So first, check the call site.

Was the “new” keyword used?

Now that you see the call site, ask yourself this question: “Was the new keyword used? Using the “new” keyword (also known as constructor hijacking) will make “this” use the newly created object as its value.

function Moola(){
  console.log(this)
  //new object created
  //from constructor
}
var obj = new Moola(); //this is the call site

Was it called with an “owning” object?

If the function is called with a “dot” before it, meaning it has an “owning” object – then “this” is that object. Though this may be the most common way to tell what “this” is – it gets confusing without knowing the other ways of binding “this”.

obj = {
  someFunc : function(){
    console.log(this);
    //current object
  }
}
obj.someFunc(); //this is the call site

Did the call site use .apply() or .call()?

Now this is a known as “explicit” binding – which is a more dynamic way of utilizing the “this” keyword. With .call() or .apply(), you can pass in an object that you want to use for your “this” keyword. Confusing? It’s a way to make your functions more “flexible” – remember I mentioned Javascript is a truly expressive language.

function someFunc(){
  console.log(this)
  //if .call or .apply is used,
  //the parameter passed is the value
  //of "this"
}
var obj = {};
someFunc.call(obj);
someFunc.apply(obj);

The difference between .call() and .apply() is that .apply() you have the option of passing a second parameter as the arguments for the executing function.

The Global Object

Finally, if none of the above were used at the call site, the “this” keyword contains the global (window) object. This is true even if you’re in a function (no matter how many levels deep), and you simply log “this” – you get the “window” object.

function someFunc(){
  console.log(this)
  //logs "window"
}

Thanks to Kyle Simpson who finally made this subject clear to me – after years of confusion. You should really check out his series “You Don’t Know JS“. Kyle has a way of teaching that is strategical and fun at the same time.

Leave a Comment.