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
| Feature | Regular Function | Arrow Function |
|---|---|---|
Own this | Yes | No |
this determined by call site | Generally yes | No; inherited lexically |
Can use call() or apply() to set this | Yes | No; these methods cannot change its lexical this |
| Suitable for object methods needing their own receiver | Yes | Usually no |
Suitable for callbacks that inherit surrounding this | Sometimes | Often |
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.