While working with JavaScript, you’ll inevitably come across the this keyword. As a concept, it can be quite tricky to grasp! Normally this refers to the object that owns the method. However, its meaning is entirely different — depending on how the function is called.

In this article, we’ll be looking at this in detail.

A little background

Objects are the basic building blocks of JavaScript! And the this keyword will always refer to an object. You can check its current value at every line of code execution. The value of this is determined based on the code’s execution context.

Execution Context

JavaScript code is read and executed line by line. The environment (or scope), of the line currently being executed, is known as Execution Context.

Behind the scenes, JavaScript runtime is maintaining a stack of these execution contexts and the context present at the top of this stack — is the one currently being executed.

The object that this refers to changes every time the execution context is changed.

This is why this can be difficult to understand! Let’s look at this in a number of different contexts — so we can learn how it works!

“this” in Global Scope

If there is no current object, this refers to the global object. Within our browser that happens to be the window object.* *It’s the top-level object which represents the document.

Let’s test to confirm:

function testThis() { 
   console.log(this === window); 
} 

testThis(); 
// returns true

console.log(this === window) 
// returns true

“this” when calling Function

The value of this remains as the global object if you’re calling a function:

window.check = "Hi! I'm the window object";

function thisFunction() {
	alert(this.check); // Hi! I'm the window object
	alert(window === this); // true
}

thisFunction();

“this” in Methods

When we call a function as a method of an object, this refers to the object, which is then known as the receiver of the function call.

In the following example, the method quote is inside an object called author. The quotes‘ this value refers to author itself. So the author object will receive the quote method call:

const author = {
  name: "Oscar Wilde",
  quote() {
    console.log(`Be yourself. Everyone else is already taken. - ${this.name}`);
  }
};
author.quote();

“this” with call() and apply()

A function’s this value is set implicitly, however, we can also call a function with an explicit this argument with call() and apply().

Essentially, call() and apply() run JavaScript functions as if they were methods of another object.

Let’s see an example:

function testThis(type) {
   this.test = "I'm the "+type+"!";
}

let firstObject = {};
testThis.call(firstObject, "firstObject");

console.log(firstObject.test); 
// I'm the firstObject

let secondObject = {};
testThis.apply(secondObject, ["secondObject"]);

console.log(secondObject.test); 
// I'm the secondObject

The only difference is that call() expects a discrete number of parameters while apply() can be passed an array of parameters.

Note: If you’re using call or apply outside of strict mode, then passing null or undefined using call or apply will be ignored by the JavaScript engine. This is one of the reasons why it is usually suggested to always write code in strict mode!

“this” with bind()

The bind() method allows us to permanently tie a this argument to a value. So in the below example, bind will create a new quote function and set its this value to author.

const author = {
  name: "Oscar Wilde",
  quote() {
    console.log(`Be yourself. Everyone else is already taken. - ${this.name}`);
  }
};
setTimeOut(author.quote.bind(author), 1000);

By doing so, our this cannot be changed with the call or apply methods.

“this” inside an Arrow Function

Using this with an arrow function is different from any other kind of JavaScript function. An arrow function uses the this value from its enclosing execution context since it does have one of its own.

An arrow function permanently captures the this value, preventing apply or call from being able to change it later on.

For example:

const author = this;

const oscarWilde = () => {
  console.log(this === oscarWilde);
};

oscarWilde();
// false

Here, we are storing the value of a this in a variable and then comparing the value with a this value that is inside an arrow function.

An arrow function’s this value cannot be set explicitly! Also, the arrow function will ignore any attempt to pass a value to this using methods like callapply, and bind. An arrow function will refer to the this value that was set when the arrow function was created.

Note: An arrow function can also not be used as a constructor. So we cannot assign properties to this inside an arrow function.

In Summary…

So now, you can figure out the value of this with these simple rules:

  • By default, this refers to global object — within the browser, this is the window object.
  • When a method is called as a property of object, this refers to the parent object.
  • When a function is called with a new operator, this refers to the newly created instance.
  • When a function is called using call() and apply(), then this refers to the value passed as the first argument of the method.

Conclusion

And there we go! We’ve looked at how this works in a number of different contexts, such as global scope, functions, methods, call()apply()bind(), and arrow functions!