this Keyword: How Execution Context WorksIn JavaScript, this refers to the object that is currently executing a function or method. Unlike regular variables that follow lexical scope, this is determined dynamically by how a function is called—unless you use an arrow function.
this Binding Rulesflowchart TD
Call["How was the function called?"] --> Arrow{"Arrow function?"}
Arrow -- "Yes" --> Lex["Inherits outer lexical this"]
Arrow -- "No" --> New{"Called with new?"}
New -- "Yes" --> Inst["Points to new instance"]
New -- "No" --> Expl{"call / apply / bind?"}
Expl -- "Yes" --> Given["Points to passed object"]
Expl -- "No" --> Method{"Called as obj.fn()?"}
Method -- "Yes" --> Owner["Points to obj before dot"]
Method -- "No" --> Plain["undefined (strict) or global"]
this and Fixing It with bind() or Arrow FunctionsPassing user.greet directly as a callback strips away user before the dot, making this equal undefined inside greet. Fix that by wrapping in an arrow function or calling .bind(user).
const tracker = {
label: "Downloads",
count: 0,
increment() {
this.count += 1;
console.log(`${this.label}: ${this.count}`);
},
};
tracker.increment(); // this === tracker
// Explicit binding with bind() preserves tracker context
const detachedIncrement = tracker.increment.bind(tracker);
detachedIncrement();
// call() invokes immediately with a custom this
function announce(prefix) {
console.log(`${prefix} ${this.label} = ${this.count}`);
}
announce.call(tracker, "[Metric]");
obj.method directly to setTimeout or addEventListener: Detached methods lose their obj context. Bind them with obj.method.bind(obj) or wrap () => obj.method().const user = { name: "Ali", say: () => this.name } fails because arrow functions inherit this from the outer module scope, not user.this inside DOM event listeners: Inside a regular function (e) {} listener, this refers to the DOM element, whereas inside an arrow listener this refers to the outer scope.call(), apply(), and bind()?call(ctx, a, b) and apply(ctx, [a, b]) invoke the function immediately with this set to ctx. bind(ctx) returns a brand-new bound function to call later.
this inside a global strict-mode function?Calling a standalone regular function in strict mode sets this to undefined, preventing accidental edits to global window properties.
this when passed as callbacks?Class methods run in strict mode and are not auto-bound, so extracting const fn = instance.save; disconnects this unless you bind it or use an arrow property.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.
You've completed this section! Take a quick 5-question quiz to check your understanding.