Demystifying 'this' in JavaScript
How this actually binds in JS: default, implicit, explicit, new, and why arrow functions ignore you.
this is the keyword everyone pretends to understand until a callback breaks production. It isn't magic. It's "who called this function."
Default binding
Call a plain function in the global scope and this is usually window in browsers (strict mode can make it undefined).
function sayHi() {
console.log(this);
}
sayHi();
Implicit binding
Method call sets this to the owner object.
const person = {
name: "Pantelis",
greet: function () {
console.log(`Hello, my name is ${this.name}`);
},
};
person.greet();
Explicit binding
call, apply, and bind let you choose this.
function introduce(language) {
console.log(`My name is ${this.name} and I code ${language}`);
}
const person = { name: "Pantelis" };
introduce.call(person, "JavaScript");
introduce.apply(person, ["JavaScript"]);
bind returns a new function with this locked in:
const introducePantelis = introduce.bind(person, "JavaScript");
introducePantelis();
Use call/apply when you invoke now. Use bind when you pass the function around (event handlers, timers).
new binding
new creates an object and points this at it inside the constructor.
function Dog(name) {
this.name = name;
}
const dog1 = new Dog("Rocky");
console.log(dog1.name);
Arrow functions
Arrows don't get their own this. They inherit from the surrounding scope.
const outer = {
inner: () => {
console.log(this);
},
};
outer.inner(); // global object in sloppy browser globals
That's why arrows inside object methods can surprise you. Great for callbacks when you want lexical this. Bad when you need dynamic this on the method itself.
Pitfalls
Losing this in callbacks is still common. bind fixes it. So does storing const self = this if you're old school.
Practice beats reading. Log this in weird places until it's boring.