Function this Keyword in JavaScript
In JavaScript, the this
keyword is a special identifier that refers to the context in which a function is executed. It’s one of the most powerful yet often confusing concepts in JavaScript because its value depends on how and where a function is called — not just where it is defined.
Understanding this
is essential for working with objects, classes, event handlers, and asynchronous code in JavaScript.
1. Dynamic this
in Regular Functions
In regular functions, the value of this
is determined at runtime (when the function is called), not when it is defined.
That’s why we call it dynamic binding.
Depending on how the function is called, this
can refer to:
- The global object (
window
in browsers,global
in Node.js) - The object that owns the method
- A new instance (when called with
new
) - undefined (in strict mode)
Global Context
When a regular function is called without an object,
this
refers to the global object (or undefined
in strict mode).
function showThis() {
console.log(this);
}
showThis();
// In browser: Window object
// In strict mode: undefined
Object Method Context
When a function is called as a method of an object,
this
refers to the object that owns the method.
const person = {
name: "Alice",
greet: function() {
console.log(this.name);
}
};
person.greet(); // Output: "Alice"
Constructor Function Context
When a function is used with the new
keyword,
this
refers to the newly created object instance.
function User(name) {
this.name = name;
}
const user1 = new User("Bob");
console.log(user1.name); // Output: "Bob"
Explicit Binding (call, apply, bind)
JavaScript lets you manually set the value of this
using:
call()
apply()
bind()
function introduce() {
console.log(`Hi, I'm ${this.name}`);
}
const person = { name: "Charlie" };
introduce.call(person); // Hi, I'm Charlie
introduce.apply(person); // Hi, I'm Charlie
const boundFunc = introduce.bind(person);
boundFunc(); // Hi, I'm Charlie
2. Lexical this
in Arrow Functions
Unlike regular functions, arrow functions do not have their own this
.
Instead, they inherit this
from the surrounding (lexical) scope at the time of definition.
This is known as lexical scoping of this
.
Example: Lexical this
const person = {
name: "Diana",
greet: function() {
const inner = () => {
console.log(this.name);
};
inner();
}
};
person.greet(); // Output: "Diana"
Arrow Function in Event Handlers
In event handlers, arrow functions are often useful because they retain the this
from the outer scope.
function Counter() {
this.count = 0;
document.body.addEventListener("click", () => {
this.count++;
console.log(this.count);
});
}
new Counter();
Arrow Functions vs Regular Functions (this
Behavior)
Aspect | Regular Function | Arrow Function |
---|---|---|
Own this | Yes (dynamic) | No (inherits from parent) |
this determined by | Call-time | Definition-time |
Common use | Methods, constructors | Callbacks, event handlers |
Can be used as constructor? | Yes | No |
Typical problem solved | Manual binding needed | Avoids binding issues |
Example Comparison
const obj = {
value: 100,
regularFunc: function() {
setTimeout(function() {
console.log(this.value); // undefined
}, 1000);
},
arrowFunc: function() {
setTimeout(() => {
console.log(this.value); // 100
}, 1000);
}
};
obj.regularFunc();
obj.arrowFunc();
3. When to Use Which
Use Regular Functions when:
- You need dynamic
this
binding (e.g., object methods, constructors). - You want to define methods that can change context with
.call()
or.bind()
.
Use Arrow Functions when:
- You want to preserve the parent scope’s
this
. - Writing short callbacks, event listeners, or higher-order functions.