What does the this keyword in JavaScript mean? 

And how can you use it practically in your JavaScript program?

 These are some of the common questions that newbies and even some experienced JavaScript developers ask about the this keyword.


If you're one of those developers wondering what the this keyword is all about, then this article is for you. Explore what this refers to in different contexts and familiarize yourself with some gotchas to avoid confusion, and of course, bugs in your code.

"this" Inside the Global Scope

In the global context, this will return the window object as long as it's outside a function. Global context means that you don't place it inside a function.

 if(true) {
  console.log(this) // returns window object
}

let i = 2
while(i < 10) {
  console.log(this) // returns window object till i === 9
  i++
}

If you run the above code, you'd get the window object.

"this" Inside Functions (Methods)

When used inside of functions, this refers to the object that the function is bound to. The exception is when you use this in a standalone function, in which case it returns the window object. Let's see some examples.

In the following example, the sayName function is inside the me object (i.e., it's a method). In cases like this, this refers to the object containing the function.

  
function sayName() {
  return `My name is ${this.name}`
}

const me = {
  name: "Kingsley",
  sayName: sayName
}

console.log(me.sayName()) // My name is Kingsley

this is the me object, so saying this.name inside the sayName method is exactly the same as me.name.

Another way to think of it is that whatever is on the left side of the function when invoked will be this. This means that you can reuse the sayName function in different objects and this will refer to a completely different context each time.

Now, as earlier mentioned, this returns the window object when used inside a standalone function. This is because a standalone function is bound to the window object by default:

 function talk() {
  return this
}

talk() // returns the window object

Calling talk() is the same as calling window.talk(), and anything that's on the left side of the function will automatically become this.

On a side note, the this keyword in the function behaves differently in JavaScript's strict mode (it returns undefined). This is also something to keep in mind when you're using UI libraries that use strict mode (e.g. React).

Using "this" With Function.bind()

There may be scenarios where you can't just add the function to an object as a method (as in the last section).

Perhaps the object is not yours and you're pulling it from a library. The object is immutable, so you can't just change it. In cases like this, you can still execute the function statement separately from the object using the Function.bind() method.

In the following example, the sayName function isn't a method on the me object, but you still bound it using the bind() function:

 function sayName() {
  return `My name is ${this.name}`
}

const me = {
  name: "Kingsley"
}

const meTalk = sayName.bind(me)

meTalk() // My name is Kingsley

Whatever object you pass into bind() will be used as the value of this in that function call.

In summary, you can use bind() on any function and pass in a new context (an object). And that object will overwrite the meaning of this inside that function.

Using "this" With Function.call()

What if you don't want to return a whole new function, but rather just call the function after binding it to its context? The solution for that is the call() method:

 function sayName() {
  return `My name is ${this.name}`
}

const me = {
  name: "Kingsley"
}

sayName.call(me) // My name is Kingsley

The call() method immediately executes the function instead of returning another function.

If the function requires a parameter, you can pass it via the call() method. In the following example, you're passing the language to the sayName() function, so you can use it to conditionally return different messages:

 function sayName(lang) {
  if (lang === "en") {
    return `My name is ${this.name}`
  } else if (lang === "it") {
    return `Io sono ${this.name}`
  }
}

const me = {
  name: "Kingsley"
}

sayName.call(me, 'en') // My name is Kingsley
sayName.call(me, 'it') // Io sono Kingsley

As you can see, you can just pass any parameter you want to the function as the second argument to the call() method. You can also pass as many parameters as you want.

The apply() method is very similar to call() and bind(). The only difference is that you pass multiple arguments by separating them with a comma with call(), whereas you pass multiple arguments inside an array with apply().

In summary, bind(), call(), and apply() all allow you to call functions with a completely different object without having any sort of relationship between the two (i.e. the function isn't a method on the object).

"this" Inside Constructor Functions

If you call a function with a new keyword, it creates a this object and returns it:

 function person(name){
  this.name = name
}

const me = new person("Kingsley")
const her = new person("Sarah")
const him = new person("Jake")

me.name // Kingsley
her.name // Sarah
him.name // Jake

In the above code, you created three different objects from the same function. The new keyword automatically creates a binding between the object that is being created and the this keyword inside the function.

"this" Inside Callback Functions

Callback functions are different from regular functions. Callback functions are functions that you pass to another function as an argument, so they can be executed immediately after the main one has finished executing.

The this keyword refers to an entirely different context when used inside callback functions:

 function person(name){
  this.name = name
  setTimeout(function() {
    console.log(this)
  }, 1000)
}

const me = new person("Kingsley") // returns the window object

After one second of calling the person constructor function and creating a new me object, it'll log the window object as the value of this. So when used in a callback function, this refers to the window object and not the "constructed" object.

There are two ways to fix this. The first method is using bind() to bind the person function to the newly constructed object:

 function person(name){
  this.name = name
  setTimeout(function() {
    console.log(this)
  }.bind(this), 1000)
}

const me = new person("Kingsley") // returns the me object

With the above modification, this in the callback will point to the same this as the constructor function (the me object).

The second way to solve the problem of this in callback functions is by using arrow functions.

"this" Inside Arrow Functions

Arrow functions are different from regular functions. You can make your callback function an arrow function. With arrow functions, you no longer need bind() because it automatically binds to the newly constructed object:

 function person(name){
  this.name = name
  setTimeout(() => {
    console.log(this)
  }, 1000)
}

const me = new person("Kingsley") // returns the me object

Learn More About JavaScript

You've learned all about the "this" keyword and what it means in all the different contexts in JavaScript. If you're new to JavaScript, you'll greatly benefit from learning all the basics of JavaScript and how it works.