The This Keyword And Arrow Function Context
How does a shared function know which object called it? The answer lies in the dynamic, often confusing 'this' keyword.
The most important keyword in Object-Oriented Programming is undoubtedly this. In the previous part, we moved our functions to a shared store. But this introduced a problem: if 1,000 users share one increment function, how does that function know whose score to increase?
The solution is the this keyword.
The Essentials
- Implicit Parameter:
thisis a variable that is automatically created in every execution context. - Left of the Dot: By default,
thispoints to the object on the left-hand side of the dot when the method is called. - The Nested Function Trap: If you call a regular function inside a method,
thisloses its connection to the object and defaults to the globalwindow. - Arrow Functions: A modern fix that borrows
thisfrom the surrounding (lexical) scope.
ExpandDynamic this Binding
The Dynamic Reference
When we call user1.increment(), JavaScript doesn't just run the code; it sets up a dynamic reference.
const userFunctionStore = {
increment: function() {
// 'this' is automatically created here
this.score++;
}
};When you write this.score++, you are saying: "Look at the object that called me and change its score."
The "Left of the Dot" Rule
- Call
user1.increment()->thisisuser1. - Call
user2.increment()->thisisuser2.
It's a beautiful system that allows one function to serve millions of objects.
The Trap: Losing Context
Imagine you want to break your logic into smaller helper functions:
const userFunctionStore = {
increment: function() {
function addOne() {
this.score++; // DANGER: 'this' is now 'window'
}
addOne();
}
};When addOne() is called, it's not being called with a dot (something.addOne()). Because there is no object to the left of the dot, JavaScript defaults this to the global object (window). Your code will try to increment window.score, which is likely undefined, leading to a bug.
The Legacy Hack: that = this
In the old days, developers used a hack to "save" the context:
increment: function() {
const that = this; // Capture the correct 'this'
function addOne() {
that.score++; // Use the captured reference
}
addOne();
}The Modern Fix: Arrow Functions
ES6 introduced Arrow Functions, which behave differently. They don't create their own this. Instead, they inherit this from where they were defined (Lexical Scoping).
const userFunctionStore = {
increment: function() {
const addOne = () => {
this.score++; // Inherits 'this' from the increment context
};
addOne();
}
};By using an arrow function, addOne looks "outside" to the increment execution context, finds the correct this (the user object), and everything works perfectly.
Why This Matters
Mastering this is the difference between a junior and a senior engineer. It's the key to making shared functionality truly flexible. But even with this and the prototype chain, the code is still a bit manual. In the next part, we'll see how the new keyword automates the entire process.
Further Reading and Watching
- Video: The this Keyword Explained
- MDN: this reference
- Concept: Arrow functions vs Regular functions
Keep reading