Published: 2017/07/12 Reading Time: 5 minutes

All About This in JavaScript

This in JavaScript: What does it mean?If you've been doing web development for any amount of time, you've probably heard of the this keyword in JavaScript. this in JavaScript can be confusing for beginning developers because sometimes the keyword doesn't reference, or refer to, what you think it will.

How This is Determined in JavaScript

So, what does this actually reference? A function's this keyword is used to reference an Object, but not always the current function (that's right, functions are just a type of object in JavaScript). The value of this is usually determined by how the function is called, and can change depending on a function's use. The value is also determined differently depending on whether the function is running in 'strict mode' or not, or if you're using the ES6-introduced arrow functions. With that in mind, it's no wonder that developer's can get mixed up on what the this keyword is actually referencing. Thankfully, if we ever need to override the implicit context, there are some native functions that help us explicitly define and control the context of the this keyword in different ways. This is referred to as explicit binding , and is fundamental to learning JavaScript. But first, let's touch on what determines the default value of this in JavaScript, otherwise referred to as implicit binding.

What is Implicit Binding?

Implicit binding is when the contextual reference of this in JavaScript is handled by the engine that parses JavaScript (like Chrome's V8 Engine). Generally, this will refer to the context of the function invocation, not the context of the definition (or even, as you might expect, the current block scope). A good way to look at it is this inside of a function usually refers to the object to the left of the dot upon which the function was called. Confused? Don't worry! Let's explain that more in this example:

const randomFunction = function() {
    console.log(this);
};


randomFunction(); // Returns the 'Window' object since this is the same as writing Window.randomFunction();


const newObj = {
    whatsThis: function() {
        console.log(this);
    }
};


newObj.whatsThis(); // Returns the 'newObj' object.

This is implicit binding of the this keyword, and is the common sense determination of the engine as it reads your JavaScript. In most cases, this implicit binding is enough and works pretty well. But, sometimes, you need more control.

Explicit Binding in JavaScript

There are 3 methods in JavaScript for explicitly defining the context of this. They are .call(), .apply(), and (the most common) .bind(). For the sake of explanation, let's take the previous example and assume we have a situation like this:

const oldObj = {
    whatsThis: function() {
        console.log(this);
    }
};


oldObj.whatsThis(); // Returns the 'oldObj' object.


const newObj = {
    whatsThis: function() {
        oldObj.whatsThis();
    }
};

newObj.whatsThis(); // Returns the 'oldObj' object.

In this example, we are reusing oldObj.whatsThis() within another object's method. This is a bit confusing, but the important thing to notice here is that the context of whatsThis() looks like it has changed to newObj; However, since that method is actually calling a function from inside the oldObj, the this keyword is still referencing that original object. There are a few ways to force newObj.whatsThis() to reference newObj if you need to.

How to Explicitly Define This in JavaScript

.bind() is a method on a function to return a new function with a defined context for this. It's a little confusing unless you see it, so here it is in action:

const oldObj = {
    whatsThis: function() {
        console.log(this);
    }
};


oldObj.whatsThis(); // Returns the 'oldObj' object.


const newObj = {
    whatsThis: function() {
        return oldObj.whatsThis.bind(this); // Set the context to the current object.
    }
};


const newFunc = newObj.whatsThis();


newFunc(); // Returns the 'newObj' object.

Now, this is may be a little confusing, but stay with me. Why did we have to assign the newObj.whatsThis() method to a new variable, instead of just invoking it? This brings up a good distinction between .bind() and .call() or .apply(). The former will return a new function with the appropriate context for this. The later two will invoke that function. So, if we wanted to just run the function instead of returning it, you could do this:

const newObj = {
    whatsThis: function() {
        oldObj.whatsThis.apply(this); // Set the context to the current object.
    }
};


newObj.whatsThis(); // Returns the 'newObj' object.

So, use .bind() if you want to save the function (with the context bound) for later use, or use .apply() if you want to invoke that function (with the context bound) immediately.

The Difference Between Call and Apply

The last option is to use .call(). In my opinion, you'll almost always default to using .apply(), but it doesn't really matter unless you're dealing with legacy or third-party code. The only difference between the two is the way they receive optional arguments to pass to the original function they are invoking. Here it is for reference:

  • .call(context, arg1, arg2, arg3)
  • .apply(context, [arg1, arg2, arg3])

The only difference, then, is that .call() receives individual arguments while .apply() receives an array of those parameters. As you probably have guessed by now, the this keyword is nice but unfortunately hard to follow at times — especially if your call stack (the chain of function calls) is long and deep. However, for those pesky times where you might have to use this, you can now rest assured that you've wrapped your mind around the basics. Good job! There's just one last thing I want to make you aware of, and it might surprise you...

Avoid Using This in JavaScript

So, maybe you're asking: "Do I have to use this at all?" — and that's a great question. The answer is sometimes. But most of the time you should avoid it. In fact, there's an entire programming methodology that focuses on avoiding this (among other things) called Functional Programming, and it's all the rage in JavaScript right now. Without going into too much detail, the idea is to use what are called "pure functions". They are called "pure" because they are predictable; meaning, you should never have to worry about the context of this with them, because they will always output the same result if they are given the same input. I strongly recommend checking it out, and the linked-to book above is a wonderfully free resource.