this and bind/apply/call methods
this and bind/apply/call methods in object context in JavaScript
In JavaScript, this
is a special keyword that refers to the object in whose context the code is executing. But since JavaScript has dynamic context, this
can change depending on how the function is called.
When working with objects, this
can often be confusing. In this article, we'll look at how this
works in object context and how to control it using bind
, call
, and apply
methods.
const user = {
name: 'Anna',
greet() {
console.log(`Hi, I'm ${this.name}`);
}
};
user.greet(); // Hi, I'm Anna
Here this
points to the user
object because greet
is called as user.greet()
.
const user = {
name: 'Anna',
greet() {
console.log(`Hi, I'm ${this.name}`);
}
};
setTimeout(user.greet, 1000); // Hi, I'm undefined (or error in strict mode)
When we pass user.greet
without calling it, this
loses its original context and becomes undefined
or window
(in non-strict mode).
bind()
const user = {
name: 'Anna',
greet() {
console.log(`Hi, I'm ${this.name}`);
}
};
const boundGreet = user.greet.bind(user);
setTimeout(boundGreet, 1000); // Hi, I'm Anna
bind()
returns a new function where this
is permanently bound to the user
object.
Advantages:
call()
and apply()
methods
function introduce(city, country) {
console.log(`${this.name} from ${city}, ${country}`);
}
const person = { name: 'Mariam' };
introduce.call(person, 'Yerevan', 'Armenia'); // Mariam from Yerevan, Armenia
introduce.apply(person, ['Gyumri', 'Armenia']); // Mariam from Gyumri, Armenia
call()
and apply()
immediately invoke the function while changing this
, whereas bind()
returns a new function without invoking it.
Difference between call and apply:
call()
takes arguments as separate valuesapply()
takes arguments as an array
const obj = {
name: 'Mark',
outer() {
console.log(this.name); // Mark
function inner() {
console.log(this.name); // undefined
}
inner();
}
};
obj.outer();
The inner inner()
function is a regular function, not a method, so this
loses its binding.
We can solve this by using:
this
// Arrow function solution
outer() {
console.log(this.name);
const inner = () => {
console.log(this.name); // correct this
};
inner();
}
const button = document.querySelector('button');
const user = {
name: 'Ani',
handleClick() {
console.log(`Clicked by ${this.name}`);
}
};
button.addEventListener('click', user.handleClick.bind(user));
If we don't use bind()
, this
will become the button
DOM element.
this
in JavaScript always depends on how the function is called. In object context, it's one of the fundamental tools for managing code structure. The bind()
, call()
, and apply()
methods allow you to control context and create clean, predictable code.