JavaScript "this" Keyword
šÆ JavaScript this Cheatsheet
The value of this depends on how a function is called. Understanding the different binding rules helps you predict and control this in any context.
ā Global binding ā Implicit binding ā Explicit binding ā New binding ā Arrow functions and this
#javascript #this #scope #functions #objects #binding #webdev #frontend #coding #tips
Global binding
In the global scope or a regular function not called as a method, this refers to the global object:
console.log(this); // window in browsersfunction showThis() {
console.log(this);
}
showThis(); // windowIn strict mode, this is undefined:
"use strict";
function showThis() {
console.log(this);
}
showThis(); // undefinedImplicit binding
When a method is called on an object, this refers to that object:
const user = {
name: "Ada",
greet() {
return `Hello, ${this.name}`;
},
};
user.greet(); // "Hello, Ada"Explicit binding
Losing implicit binding is a common problem:
const greet = user.greet;
greet(); // "Hello, undefined" (this is window or undefined)In this case, use call, apply, or bind to set this explicitly.
function introduce(skill) {
return `${this.name} knows ${skill}`;
}
const person = { name: "Grace" };
introduce.call(person, "JavaScript"); // "Grace knows JavaScript"
introduce.apply(person, ["Python"]); // "Grace knows Python"
const introduceGrace = introduce.bind(person);
introduceGrace("CSS"); // "Grace knows CSS"New binding
When a function is called with new, this refers to the new object being constructed.
function User(name) {
this.name = name;
}
const ada = new User("Ada");
console.log(ada.name); // "Ada"Arrow functions and this
Arrow functions do not have their own this. They inherit this from the surrounding scope.
const team = {
name: "Engineering",
members: ["Ada", "Grace"],
logMembers() {
// prettier-ignore
this.members.forEach(
(member) => {
console.log(`${member} is in ${this.name}`);
}
);
},
};
team.logMembers();
// "Ada is in Engineering"
// "Grace is in Engineering"Event listeners
Due to this behavior, arrow functions are usually the wrong choice for event listeners that requires the DOM element.
const button = document.querySelector("button");
button.addEventListener("click", function () {
console.log(this); // <button>
});Nested functions
A regular nested function does not inherit this from its parent method.
const user = {
name: "Ada",
delayedGreet() {
setTimeout(function () {
console.log(`Hello, ${this.name}`); // this is window
}, 100);
},
};Use an arrow function to preserve this.
const user = {
name: "Ada",
delayedGreet() {
setTimeout(() => {
console.log(`Hello, ${this.name}`); // "Hello, Ada"
}, 100);
},
};Full-Stack AI Developer Roadmap
From HTML & CSS to working with AI models, all in one structured roadmap.