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.