Arrow functions look like shortcuts — but they behave differently from traditional functions in crucial ways. Here’s what you need to know.

Introduction: Not Just Shorter Syntax
When ES6 introduced arrow functions, most developers thought: “Cool, fewer characters to type.”
But arrow functions are not just shorter syntax. They change how this
, arguments
, and scoping work. In fact, mixing them up without understanding the differences can cause subtle bugs that are frustrating to debug.
In this post, we’ll break down the 7 key differences between arrow functions and traditional functions, with clear examples and fixes. By the end, you’ll know exactly when to use which.
1. this
Binding (Lexical vs Dynamic)
Traditional Functions
Each traditional function has its own this
, determined by how it’s called.
function User(name) {
this.name = name;
this.sayHi = function() {
console.log("Hi, I’m " + this.name);
};
}
const u = new User("Ali");
u.sayHi(); // "Hi, I’m Ali"
Arrow Functions
Arrow functions don’t bind their own this
. They inherit this
from their surrounding scope (lexical).
function Timer() {
this.seconds = 0;
setInterval(() => {
this.seconds++; // ✅ Refers to Timer instance
}, 1000);
}
const t = new Timer();
setTimeout(() => console.log(t.seconds), 3100); // ~3
💡 Key Point:
- Use arrows when you want to preserve outer
this
. - Use traditional functions when you need dynamic
this
(e.g., object methods).
2. Constructors (new
)
Traditional Functions
You can use traditional functions as constructors with new
.
function Person(name) {
this.name = name;
}
const p = new Person("Sara");
console.log(p.name); // "Sara"
Arrow Functions
Arrows cannot be used as constructors.
const Person = (name) => {
this.name = name;
};
const p = new Person("Sara");
// ❌ TypeError: Person is not a constructor
💡 Key Point:
If you need a constructor or prototype methods, stick with regular functions or ES6 class
.
3. arguments
Object
Traditional Functions
Traditional functions provide the special arguments
object.
function logAll() {
console.log(arguments);
}
logAll(1, 2, 3);
// [1, 2, 3]
Arrow Functions
Arrows don’t have their own arguments
.
const logAll = () => {
console.log(arguments);
};
logAll(1, 2, 3);
// ❌ ReferenceError: arguments is not defined
The Fix → Rest Parameters
const logAll = (...args) => {
console.log(args);
};
logAll(1, 2, 3);
// [1, 2, 3]
💡 Key Point:
- Use
arguments
with traditional functions. - Use
...rest
with arrow functions.
4. Implicit Return
Traditional Functions
Always need return
explicitly.
function double(x) {
return x * 2;
}
Arrow Functions
Allow implicit returns for single expressions.
const double = x => x * 2;
For objects, wrap in parentheses:
const makeUser = (id, name) => ({ id, name });
💡 Key Point:
Arrows are great for one-liners and clean callbacks.
5. Hoisting
Traditional Functions
Function declarations are hoisted — you can call them before they’re defined.
sayHi(); // ✅ Works
function sayHi() {
console.log("Hello!");
}
Arrow Functions
Arrow functions are not hoisted because they’re variables.
sayHi(); // ❌ ReferenceError
const sayHi = () => console.log("Hello!");
💡 Key Point:
- Use declarations if you need hoisting.
- Use arrows when function order is clear.
6. Methods in Objects
Traditional Functions → Work fine
const user = {
name: "Ali",
greet: function() {
return "Hi " + this.name;
}
};
console.log(user.greet()); // "Hi Ali"
Arrow Functions → Break this
const user = {
name: "Ali",
greet: () => "Hi " + this.name
};
console.log(user.greet());
// "Hi undefined"
💡 Key Point:
Don’t use arrows as object methods if you need this
.
7. Suitability in Callbacks
Traditional Functions
Verbose in callbacks:
[1, 2, 3].map(function (n) {
return n * 2;
});
Arrow Functions
Much cleaner:
[1, 2, 3].map(n => n * 2);
💡 Key Point:
Arrows are the natural choice for array methods, event listeners, and async code.
Wrapping It All Up
Here are the 7 key differences:
this
→ Arrows use lexicalthis
, traditional functions use dynamic.- Constructors → Only traditional functions can be used with
new
. arguments
→ Available in traditional, not in arrows.- Return → Arrows allow implicit return.
- Hoisting → Traditional functions are hoisted, arrows are not.
- Methods → Use traditional functions for object methods.
- Callbacks → Arrows are cleaner in functional programming.
Bottom line:
- Use arrow functions for callbacks, utilities, and functional programming.
- Use traditional functions for constructors, prototypes, and object methods.
Call to Action
👉 Which difference tripped you up when you first learned JavaScript? Drop it in the comments 👇.
📤 Share this with a teammate who still confuses arrow vs traditional functions.
🔖 Bookmark this post — it’s a reference you’ll need again and again.
Leave a Reply