JavaScript this Keyword

The this keyword in JavaScript refers to a value determined by how a function is called. It allows functions to access properties and methods associated with a particular object or execution context.

Understanding this is important when working with object methods, regular functions, arrow functions, constructor functions, and JavaScript classes.

Unlike some other programming languages, JavaScript does not determine the value of this solely from where a function is written. In most regular function calls, the way the function is invoked determines its value.

In this tutorial, you will learn what this means and how it behaves in different JavaScript contexts.

What Is this in JavaScript?

The this keyword refers to the value associated with the current function invocation. Its value depends on the context in which the function is executed.

Consider the following example:

const person = {
  name: "Karim",

  greet() {
    console.log(this.name);
  }
};

person.greet();

Output:

Karim

In this example, greet() is called as a method of the person object. Therefore, this refers to person, and this.name accesses its name property.

The behavior of this changes depending on how a function is called. Let’s explore the different situations.

Global Context and this

In the global context, the value of this depends on the JavaScript environment and whether the code runs as a classic script or an ES module.

In a classic browser script, top-level this refers to the global object, which is usually window.

console.log(this);

In a browser’s classic script, the output is the global window object.

In an ES module, top-level this is undefined. Node.js also has environment-specific behavior for top-level this, so the result should not be assumed to be identical across all environments.

Global this in a Browser

Consider this example in a classic browser script:

var city = "Hyderabad";

console.log(this.city);

Output:

Hyderabad

In a classic browser script, a top-level var declaration generally creates a property on window. Because top-level this refers to window, this.city accesses that property.

However, this example does not work the same way in an ES module:

var city = "Hyderabad";

console.log(this);

At the top level of an ES module, this is undefined, even though the module declares a variable named city.

Global this in Regular Functions

In a classic, non-strict browser script, a regular function called without an explicit receiver generally gets the global object as its this value.

function showThis() {
  console.log(this);
}

showThis();

In a classic, non-strict browser script, this prints the global window object.

In strict mode, the result is different:

"use strict";

function showThis() {
  console.log(this);
}

showThis();

Output:

undefined

When a regular function is called without a receiver in strict mode, this remains undefined. ES modules are automatically strict, so regular functions called this way inside modules also receive undefined.

this in Object Methods

When a function is called as a method of an object, this generally refers to the object used to call that method.

For example:

const person = {
  name: "Karim",
  age: 25,

  introduce() {
    console.log("My name is " + this.name);
    console.log("My age is " + this.age);
  }
};

person.introduce();

Output:

My name is Karim
My age is 25

Here, person.introduce() calls introduce() through the person object. Therefore, this refers to person.

Accessing Object Properties with this

You can use this to access or update properties of an object.

const car = {
  brand: "Toyota",
  year: 2024,

  showDetails() {
    console.log(this.brand);
    console.log(this.year);
  }
};

car.showDetails();

Output:

Toyota
2024

The expressions this.brand and this.year access properties belonging to the car object.

Updating Object Properties with this

The this keyword can also be used to update an object’s properties.

const user = {
  name: "Karim",

  changeName(newName) {
    this.name = newName;
  }
};

user.changeName("Ahmed");

console.log(user.name);

Output:

Ahmed

The method updates the name property of the object that calls it.

When an Object Method Is Assigned to Another Variable

A common mistake occurs when a method is assigned to a separate variable and then called independently.

const person = {
  name: "Karim",

  greet() {
    console.log(this.name);
  }
};

const greetFunction = person.greet;

greetFunction();

In strict mode, this prints undefined because the function is called without the person receiver, and this is therefore undefined. In a non-strict classic script, the result can differ because this may default to the global object.

The important point is that a function does not permanently retain the object from which it was copied. Its this value depends on how it is invoked, unless it is an arrow function or a function with a bound this.

this in Regular Functions

Regular functions determine their this value based primarily on how they are called.

Consider this example:

const person = {
  name: "Karim"
};

function showName() {
  console.log(this.name);
}

showName.call(person);

Output:

Karim

The call() method invokes showName() with person as its this value. As a result, this.name accesses "Karim".

Using call() to Set this

The call() method lets you invoke a regular function with a specified this value and individual arguments.

function introduce(city) {
  console.log(this.name + " lives in " + city);
}

const person = {
  name: "Karim"
};

introduce.call(person, "Hyderabad");

Output:

Karim lives in Hyderabad

Here, person becomes this, and "Hyderabad" is passed as the function’s argument.

Using apply() to Set this

The apply() method works similarly to call(), but it accepts the function’s arguments as an array or array-like value.

function introduce(city, country) {
  console.log(this.name + " lives in " + city + ", " + country);
}

const person = {
  name: "Karim"
};

introduce.apply(person, ["Hyderabad", "India"]);

Output:

Karim lives in Hyderabad, India

Using bind() to Set this

The bind() method creates a new function with a specified this value. Unlike call() and apply(), it does not immediately execute the function.

const person = {
  name: "Karim"
};

function greet() {
  console.log("Hello, " + this.name);
}

const boundGreet = greet.bind(person);

boundGreet();

Output:

Hello, Karim

The boundGreet function retains the bound person value for its this reference when called normally.

this in Arrow Functions

Arrow functions behave differently from regular functions. They do not have their own this value. Instead, they use the this value from their surrounding lexical context.

For example:

const person = {
  name: "Karim",

  greet() {
    const showName = () => {
      console.log(this.name);
    };

    showName();
  }
};

person.greet();

Output:

Karim

The arrow function does not create its own this. It uses the this value from the surrounding greet() method, where this refers to person.

Arrow Functions Do Not Have Their Own this

Consider the following example:

const person = {
  name: "Karim",

  greet: () => {
    console.log(this.name);
  }
};

person.greet();

This does not reliably print "Karim". The arrow function uses this from the surrounding scope where it was defined, not the person object that calls it.

For example, in an ES module, top-level this is undefined. Consequently, accessing this.name in this arrow function throws a TypeError.

For object methods that need to access the calling object through this, a regular method is generally the appropriate choice.

Arrow Functions Inside Regular Methods

Arrow functions are useful when a nested callback needs to access the same this value as its surrounding method.

const person = {
  name: "Karim",

  greet() {
    setTimeout(() => {
      console.log("Hello, " + this.name);
    }, 1000);
  }
};

person.greet();

Output after approximately one second:

Hello, Karim

The arrow function passed to setTimeout() inherits this from greet(). Because greet() was called as person.greet(), that value is person.

If a regular function were used as the callback instead, its this value would depend on how the callback was invoked by the surrounding API.

Regular Functions vs Arrow Functions

FeatureRegular FunctionArrow Function
Own thisYesNo
this determined by call siteGenerally yesNo; inherited lexically
Can use call() or apply() to set thisYesNo; these methods cannot change its lexical this
Suitable for object methods needing their own receiverYesUsually no
Suitable for callbacks that inherit surrounding thisSometimesOften

You can also learn more about JavaScript arrow functions to understand their syntax and behavior.

this in Constructor Functions

Constructor functions are regular functions traditionally used with the new keyword to create objects.

When a constructor function is called with new, JavaScript creates a new object and sets this to refer to that object during the constructor’s execution.

For example:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const person1 = new Person("Karim", 25);

console.log(person1.name);
console.log(person1.age);

Output:

Karim
25

The new Person("Karim", 25) expression creates a new object. Inside the constructor, this.name and this.age assign properties to that object.

Creating Multiple Objects

A constructor function can create multiple objects with the same structure.

function Car(brand, color) {
  this.brand = brand;
  this.color = color;
}

const car1 = new Car("Toyota", "White");
const car2 = new Car("Honda", "Black");

console.log(car1.brand);
console.log(car2.brand);

Output:

Toyota
Honda

Each call to new Car() creates a separate object. Within each constructor call, this refers to the newly created object.

For a deeper explanation of object creation, see the JavaScript constructors tutorial.

What Happens If You Forget new?

Calling a constructor function without new does not create a new object automatically.

function Person(name) {
  this.name = name;
}

const person = Person("Karim");

In strict mode, calling Person() without new makes this equal to undefined, so assigning this.name throws a TypeError. In non-strict mode, this may refer to the global object, which can accidentally create or modify a global property.

To use a constructor function correctly, call it with new:

const person = new Person("Karim");

console.log(person.name);

Output:

Karim

this in JavaScript Classes

JavaScript classes provide a structured way to create objects. Within a class constructor or an instance method, this generally refers to the instance on which the constructor or method is operating.

For example:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log("Hello, " + this.name);
  }
}

const person1 = new Person("Karim", 25);

person1.greet();

Output:

Hello, Karim

The constructor initializes properties on the new instance. When person1.greet() is called, this refers to person1.

Using this in Class Methods

Class methods can access and update instance properties through this.

class BankAccount {
  constructor(balance) {
    this.balance = balance;
  }

  deposit(amount) {
    this.balance += amount;
  }

  showBalance() {
    console.log(this.balance);
  }
}

const account = new BankAccount(1000);

account.deposit(500);
account.showBalance();

Output:

1500

The deposit() method increases the balance of the instance that calls it. The showBalance() method reads the updated property.

this in Static Methods

Static methods belong to the class itself rather than to individual instances. When a static method is called through the class, this refers to the class constructor.

class Calculator {
  static describe() {
    console.log(this.name);
  }
}

Calculator.describe();

Output:

Calculator

Here, this refers to Calculator because the static method is called through the class.

Losing this in a Class Method

If a class method is extracted and called separately, its original receiver is not automatically preserved.

class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log("Hello, " + this.name);
  }
}

const person = new Person("Karim");
const greetFunction = person.greet;

greetFunction();

In this example, the standalone method call throws a TypeError because class methods execute in strict mode, and this is undefined for the unbound call.

One solution is to bind the method:

const greetFunction = person.greet.bind(person);

greetFunction();

Output:

Hello, Karim

Binding ensures that the method uses the intended instance as its this value.

Common Mistakes When Using this

Assuming this Always Refers to the Current Object

The value of this is not always the object in which a function was originally defined. For regular functions, it usually depends on how the function is called.

Using Arrow Functions for Every Object Method

Arrow functions inherit this from their surrounding scope. If a method needs to access the object that calls it, a regular method is usually more suitable.

Forgetting new with Constructor Functions

Calling a constructor function without new does not create a new instance. It may result in an error or unintended global behavior.

Extracting a Method Without Preserving Its Receiver

Assigning an object method to a separate variable can cause it to lose its original receiver. Use bind() or call the method through the object when you need to preserve this.

Frequently Asked Questions

What does this mean in JavaScript?

The this keyword refers to a value associated with the current function invocation or lexical context. Its behavior depends on whether it is used in a regular function, arrow function, object method, constructor, or class.

What is the value of this in the global context?

In a classic browser script, top-level this refers to window. At the top level of an ES module, this is undefined. Other environments, including Node.js, have their own top-level rules.

Why does this behave differently in arrow functions?

Arrow functions do not have their own this. They inherit it from the surrounding lexical context, which makes them useful for callbacks that need to preserve the surrounding method’s this value.

How does this work in constructor functions?

When a constructor function is called with new, this refers to the newly created object during the constructor’s execution.

What does this refer to inside a class?

In an instance method called through an object, this refers to that instance. In a static method called through the class, this generally refers to the class itself.

Can I manually change the value of this?

For regular functions, you can use call(), apply(), or bind() to specify a this value. These methods cannot override the lexical this of an arrow function.

Conclusion

The JavaScript this keyword helps functions access the object or context associated with their execution.

In object methods, this generally refers to the calling object. Regular functions determine this based on how they are called, while arrow functions inherit it from their surrounding scope. Constructor functions and class instances use this to initialize and access object properties.

Once you understand these differences, you can avoid common mistakes and write more predictable JavaScript code.