Why
this.fire = function(...)and not an arrow function? Here's the full breakdown.
1οΈβ£ Introduction
JavaScript offers multiple ways to define functions:
- Function Declarations:
function greet() {} - Function Expressions:
const greet = function() {} - Arrow Functions:
const greet = () => {}
While arrow functions offer brevity and clarity, they do not have their own this , which is why choosing between the two depends entirely on your use case.
2οΈβ£ The Key Difference: this Binding
Function Expressions
Function expressions define their own this context depending on how they're called:
const obj = { count: 0, increment: function () { console.log(this); // refers to `obj` }, };
Arrow Functions
Arrow functions lexically bind this , meaning they inherit this from the surrounding context:
const obj = { count: 0, increment: () => { console.log(this); // refers to global object (or undefined in strict mode) }, };
π Why Not Use Arrow in this.fire = function (...)?
Because this refers to the object instance (Move in this case), and the fire method needs to explicitly bind thisObj or use the current instance as context.
If you used an arrow function, it would ignore thisObj and this would not refer to the Move instance or a provided scope β breaking functionality like .call():
this.fire = (o, thisObj) => { const scope = thisObj || window; // `this` here is lexically bound and can't be overridden with `.call()` this.handlers.forEach((item) => item.call(scope, o)); // β unpredictable };
3οΈβ£ When to Use Which
| Use Case | Prefer Function | Prefer Arrow Function |
|---|---|---|
Needs dynamic thisbinding | β Yes | β No |
| Callback inside method | β Yes | β
Yes (if no thisdependency) |
| Inside classes or object methods | β Yes | β No (unless explicitly static) |
| Event handlers | β Usually | β Only if you bind explicitly |
| Simple one-liners / pure funcs | β Overhead | β Perfect match |
4οΈβ£ Real Examples
β Good Use of Arrow:
const numbers = [1, 2, 3]; const squares = numbers.map(n => n * n);
β Good Use of Function Declaration:
class Timer { constructor() { this.seconds = 0; setInterval(function () { this.seconds++; // `this` needs to refer to Timer β so we bind }.bind(this), 1000); } }
β οΈ Misuse of Arrow in Object Method:
const counter = { value: 0, increment: () => { this.value++; // β `this` is not `counter` }, };
5οΈβ£ Interview Q&A
Q1: Why donβt arrow functions have their own this?
A: Because arrow functions are designed for lexical scoping. They inherit this from the context in which they are defined, rather than from how they are called.
Q2: When would using an arrow function inside a class break things?
A: When the method depends on this referring to the class instance. Arrow functions donβt have their own this, so they wonβt work properly in instance methods.
Q3: Can you replace all function expressions with arrow functions?
A: No. If the function needs a dynamic or context-based this, you must use a traditional function.
Q4: How does .call() or .apply() behave with arrow functions?
A: It has no effect. You cannot change the this value of an arrow function with .call() or .apply().
π Conclusion
Use function declarations or expressions when you rely on dynamic this, such as in methods or callbacks that depend on object context. Use arrow functions for everything else β especially in callbacks, map/reduce logic, and stateless utilities.
Test your understanding with 3 quick questions