Arrow Functions vs Regular Functions
Answer
Arrow functions (=>) are a concise syntax for writing functions introduced in ES6. They differ from regular functions in syntax, this binding, and available features.
Syntax Comparison
// Regular function
function add(a, b) {
return a + b;
}
// Arrow function
const add = (a, b) => a + b;
// Arrow with single parameter (parentheses optional)
const double = (x) => x * 2;
// Arrow with no parameters
const greet = () => "Hello!";
// Arrow with function body (needs return)
const multiply = (a, b) => {
const result = a * b;
return result;
};
Key Differences
The this Difference
// Regular function: 'this' depends on how it's called
const person = {
name: "John",
greet: function () {
console.log(`Hello, ${this.name}`);
},
};
person.greet(); // "Hello, John"
const greetFn = person.greet;
greetFn(); // "Hello, undefined" (this is lost!)
// Arrow function: 'this' is lexically bound
const person2 = {
name: "Jane",
greet: () => {
console.log(`Hello, ${this.name}`); // 'this' is outer scope!
},
};
person2.greet(); // "Hello, undefined" (outer scope's this)
Arrow Functions Solve Callback Issues
// Problem with regular functions in callbacks
const timer = {
seconds: 0,
start: function () {
setInterval(function () {
this.seconds++; // 'this' is window/undefined, not timer!
console.log(this.seconds);
}, 1000);
},
};
// Old solution: save reference to this
const timer2 = {
seconds: 0,
start: function () {
const self = this; // Save reference
setInterval(function () {
self.seconds++;
}, 1000);
},
};
// Modern solution: Arrow function
const timer3 = {
seconds: 0,
start: function () {
setInterval(() => {
this.seconds++; // 'this' is inherited from start()
console.log(this.seconds);
}, 1000);
},
};
No arguments Object
// Regular function has 'arguments'
function sum() {
console.log(arguments); // [1, 2, 3, 4, 5]
return [...arguments].reduce((a, b) => a + b);
}
sum(1, 2, 3, 4, 5); // 15
// Arrow function: no 'arguments' (use rest parameters)
const sumArrow = (...args) => {
console.log(args); // [1, 2, 3, 4, 5]
return args.reduce((a, b) => a + b);
};
sumArrow(1, 2, 3, 4, 5); // 15
Cannot Be Constructors
// Regular function can be constructor
function Person(name) {
this.name = name;
}
const john = new Person("John"); // Works
// Arrow function cannot be constructor
const Person2 = (name) => {
this.name = name;
};
const jane = new Person2("Jane"); // TypeError: Person2 is not a constructor
No prototype Property
// Regular function
function Foo() {}
console.log(Foo.prototype); // { constructor: Foo }
// Arrow function
const Bar = () => {};
console.log(Bar.prototype); // undefined
When to Use Each
| Scenario | Use |
|---|---|
| Object methods | Regular function |
| Callbacks (map, filter) | Arrow function |
| Event handlers (DOM methods) | Usually regular (for this) |
| React event handlers | Arrow function |
| Short, inline functions | Arrow function |
| Prototype methods | Regular function |
| Constructors | Regular function (or class) |
Dynamic this needed | Regular function |
Examples
// ✅ Arrow: Array methods
const doubled = [1, 2, 3].map((x) => x * 2);
const evens = [1, 2, 3, 4].filter((x) => x % 2 === 0);
// ✅ Arrow: Promises
fetch("/api/data")
.then((res) => res.json())
.then((data) => console.log(data));
// ✅ Regular: Object methods
const calculator = {
value: 0,
add(n) {
this.value += n;
return this;
},
};
// ✅ Regular: Methods needing this
document.getElementById("btn").addEventListener("click", function () {
this.classList.toggle("active"); // 'this' is the button
});
// ✅ Arrow: When you DON'T want this binding
class Counter {
count = 0;
// Arrow function to preserve 'this' in callbacks
increment = () => {
this.count++;
};
}
Key Points
- Arrow functions have shorter syntax
- Arrow functions lexically bind
this - No
argumentsobject (use rest parameters) - Cannot be used as constructors
- Perfect for callbacks and inline functions
- Use regular functions for object methods and constructors