JavaScript This Keyword — What Does This Output?
This is a daily Javascript challenge from the CodeShot archive. Practice your knowledge of Arrow Function This Binding Object Method and improve your technical interview readiness.
const obj = {
name: "Alice",
greet: function() {
return this.name
},
greetArrow: () => {
return this.name
}
}
console.log(obj.greet())
console.log(obj.greetArrow())
Detailed Explanation
Why This Question Matters
If you've spent any time with JavaScript, you've probably hit a wall with the this keyword. It’s easily one of the most confusing parts of the language because this doesn't behave like a variable—it behaves like a context.
The challenge we're looking at is a classic "gotcha" that pops up in technical interviews and, more annoyingly, in production bugs. It tests whether you actually understand the difference between regular functions and arrow functions. Most developers assume that because a function is defined inside an object, it automatically has access to that object's properties. In reality, JavaScript has very specific rules about how scope and context are bound, and those rules change depending on how you write your function.
Understanding the Code
Let's look at the snippet again:
At first glance, it looks like both functions should return "Alice". They're both methods of the same object, right? Not quite.
The first method, greet, is a standard function expression. In JavaScript, when you call a regular function as a method of an object (like obj.greet()), the this keyword is dynamically bound to the object that called it. So, this refers to obj, and this.name is "Alice".
The second method, greetArrow, is an arrow function. This is where things get tricky. Arrow functions do not have their own this binding. Instead, they use lexical scoping. This means they inherit this from the surrounding code where the function was *defined*, not where it was *called*.
In this case, the surrounding environment for obj is the global scope (or the module scope in Node.js). Since the global object (window in browsers) doesn't have a property called name, this.name returns undefined.
Finding the Correct Answer
The correct output is:
Alice
undefined
Here is the breakdown of why:
1. obj.greet(): This is a standard function call. The execution context is the object to the left of the dot. Since obj is the caller, this points to obj. Result: "Alice".
2. obj.greetArrow(): The arrow function ignores the object calling it. It looks "outside" to see what this was when the object was created. Since the object is defined in the global scope, this refers to the global object. Result: undefined.
If you were expecting the arrow function to work like the regular function, you're not alone. It's a common misconception that putting an arrow function inside an object "binds" it to that object. It doesn't.
Common Mistakes Developers Make
The biggest mistake is treating arrow functions as a "shorter version" of regular functions. They aren't just syntactic sugar; they have different behavior.
Another common trip-up happens when developers try to use arrow functions as constructors. If you try to use new with an arrow function, JavaScript will throw a TypeError because arrow functions lack the internal [[Construct]] method.
I also see people trying to fix the this issue by using .bind(), .call(), or .apply(). While those work on regular functions, they are completely ignored by arrow functions. You cannot manually rebind the this of an arrow function. Once it's set lexically, it's locked in.
Real-World Usage
You'll see this play out most often in React class components or when handling events.
Back in the day, before hooks, we had to bind every single event handler in the constructor:
this.handleClick = this.handleClick.bind(this);
We did this because when a DOM element calls a function, it changes the context of this. If you didn't bind it, this would suddenly be the HTML button instead of your component instance, and your app would crash the moment you tried to call this.setState().
This is actually where arrow functions shine. By using an arrow function for a class method (or within a setTimeout), you "capture" the correct this context from the surrounding class, preventing the context from shifting when the function is executed later.
Key Takeaways
- Regular functions have a dynamic this. It depends on *how* the function is called.
- Arrow functions have a lexical this. It depends on *where* the function was defined.
- If you need a method that accesses other properties within the same object, stick to the standard function syntax or the shorthand method syntax (greet() { ... }).
- Use arrow functions when you want to preserve the context of the outer scope, especially inside callbacks or timers.
Why this matters
Understanding Arrow Function This Binding Object Method is crucial for passing technical interviews. In real-world applications, this concept often leads to subtle bugs if not handled correctly. For more details, you can always refer to the official MDN Documentation.