this is a special keyword that refers to the object a function is currently operating on — its value is decided at call time, not at the time the function is written.
No keyword confuses JavaScript developers more than this. Think of this like the pronoun "he" in English — it refers to a different person depending on who is speaking and in what context. When Alice says "he is tall," "he" means Bob; when Charlie says it, "he" means Dave. Similarly, this inside a function refers to different objects depending on how that function is called.
This article covers the four binding rules, arrow functions, and every gotcha.
Prerequisites: JS Foundations #1 — Variables, Scope & Hoisting
1. What this Is NOT
Before learning what this is, clear two misconceptions:
thisis not the function itselfthisis not the function's lexical scope
this is a runtime binding — its value depends entirely on how the function is called, not where it's defined (arrow functions are the exception).
Loading editor...
2. this at the Global Level
At the very top of your script (outside any function), this points to the global object:
Loading editor...
This is rarely useful on its own, but it explains why a standalone function call inherits global this in non-strict mode — the function's this falls back to whatever the surrounding context is.
3. The Four Binding Rules
There are exactly four rules that determine this, in order of precedence. Before diving in, here's what the terms implicit and explicit mean in this context:
| Term | Meaning |
|---|---|
| Implicit | You don't say which object this should be — JavaScript infers it from how the function is called |
| Explicit | You directly state which object this should be, using call, apply, or bind |
Rule 1: Default Binding (lowest priority)
When a function is called standalone, this defaults to:
- Non-strict mode: the global object (
window/globalThis) - Strict mode:
undefined
Loading editor...
Important: ES modules (files loaded via <script type="module"> or bundled with Vite/Webpack) are always in strict mode. So in a real project, a standalone function call will have this as undefined, never the global object.
Rule 2: Implicit Binding
Called implicit because you never tell JavaScript which object this should be — it implies it from the call site by looking at what's to the left of the dot.
When a function is called as a method of an object, this points to that object — the one directly before the dot.
Loading editor...
The key detail: this binds to the immediate owning object:
Loading editor...
Implicit loss — extracting a method from its object loses the binding:
Loading editor...
This is the most common this bug. Why does it happen? When you pass a method as a callback, you're passing just the function — the object is left behind. setTimeout (or any API that receives a callback) calls it as a standalone function: callback(), not obj.method(). So this falls back to the default rule.
Loading editor...
The fix (before arrow functions) was explicit binding.
Rule 3: Explicit Binding — call, apply, bind
Called explicit because you explicitly tell JavaScript which object this should be — you pass it directly via call, apply, or bind instead of leaving it to inference.
You can force this to be whatever you want using these three methods. A simple way to remember them:
- call — C for Commas: arguments separated by commas
- apply — A for Array: arguments passed as an array
- bind — B for Borrow (or Bind permanently): returns a new function with
thislocked
Loading editor...
bind is permanent — once bound, this cannot be overridden, even with call or apply:
Loading editor...
Rule 4: new Binding (highest priority)
When you call a function with new, JavaScript creates a brand new object and sets it as this:
Loading editor...
What new actually does:
- Creates a fresh empty object
- Links that object's
__proto__to the constructor'sprototype - Calls the constructor with
thisset to that object - Returns the object (unless the constructor returns a non-null object)
4. Precedence Order — Tested on the Hardest Case
The priority is: new → explicit (call/apply/bind) → implicit → default
Loading editor...
When new is used on a bound function, new wins. The bound this is ignored in favor of the newly created object.
5. Arrow Functions — The Exception to Everything
Arrow functions do not have their own this. They inherit this from their enclosing lexical scope — exactly like a variable would. This is the single most important fact about arrows.
Loading editor...
Arrows cannot be bound — call, apply, and bind have no effect on them:
Loading editor...
This is why arrow functions make terrible object methods:
Loading editor...
6. this in Classes
In classes, methods use implicit binding — this is the instance. But callbacks still lose this unless you bind:
Loading editor...
7. this in Event Handlers
In DOM event handlers, this is the element that received the event:
Loading editor...
8. Quick Reference — The Four Rules
Loading editor...
Key Takeaways
| Rule | Trigger | Priority |
|---|---|---|
new | Called with new keyword | Highest |
| Explicit | call / apply / bind | High |
| Implicit | obj.method() — dot before call | Medium |
| Default | Standalone call | Lowest |
- Arrow functions break all rules — they inherit
thislexically. bindis permanent — butnewstill overrides it.- Implicit loss (extracting a method) is the #1
thisbug. - Use arrows for callbacks, regular functions / class methods for methods.
Next: JS Foundations #3 — Closures & Lexical Scope — how inner functions remember their outer scope variables, and why that powers everything from module patterns to memoization.
