, , , ,

5 Common Mistakes Developers Make with Arrow vs. Traditional Functions

Posted by

Arrow functions are powerful, but they behave differently from regular functions in tricky ways. Here’s how to avoid the most common pitfalls.

Arrow functions are powerful, but they behave differently from regular functions in tricky ways. Here’s how to avoid the most common pitfalls.

Introduction: When Functions Aren’t the Same

At first glance, arrow functions look like a shorter way of writing regular functions. Drop the function keyword, add =>, done — right?

Not exactly. Arrow functions behave differently in subtle but important ways. They don’t bind this, they don’t have arguments, and they can’t be used everywhere a traditional function can.

That’s why many developers — especially beginners — trip up when mixing arrow and traditional functions.

In this post, we’ll break down 5 common mistakes developers make when confusing arrow vs. traditional functions — with clear code examples and fixes.


1. Using Arrow Functions as Object Methods

The Mistake

const user = {
name: "Ali",
greet: () => {
return `Hi, I’m ${this.name}`;
}
};

console.log(user.greet());
// "Hi, I'm undefined"

Why It Happens

Arrow functions don’t bind their own this. Instead, they inherit from the surrounding scope. In this case, this refers to the global context, not the user object.

The Fix

Use a traditional function for methods:

const user = {
name: "Ali",
greet() {
return `Hi, I’m ${this.name}`;
}
};

console.log(user.greet());
// "Hi, I'm Ali"

💡 Rule: For object methods that rely on this, stick with traditional functions.


2. Using Arrow Functions as Constructors

The Mistake

const Person = (name) => {
this.name = name;
};

const p = new Person("Sara");
// ❌ TypeError: Person is not a constructor

Why It Happens

Arrow functions cannot be used as constructors. They don’t have their own this or a prototype property.

The Fix

Use a traditional function or class:

function Person(name) {
this.name = name;
}

const p = new Person("Sara");
console.log(p.name); // "Sara"

💡 Rule: Use traditional functions or classes when you need to construct objects.


3. Expecting arguments in Arrow Functions

The Mistake

const sum = () => {
return arguments[0] + arguments[1];
};

console.log(sum(2, 3));
// ❌ ReferenceError: arguments is not defined

Why It Happens

Arrow functions don’t have their own arguments object.

The Fix → Use Rest Parameters

const sum = (...args) => args[0] + args[1];

console.log(sum(2, 3));
// 5

💡 Rule: If you need arguments, use a traditional function. Otherwise, use rest ...args with arrows.


4. Breaking Code with Line Breaks After =>

The Mistake

// ❌ Wrong
const add = (a, b) =>
a + b;

console.log(add(2, 3));
// undefined

Why It Happens

When you put a line break right after =>, JavaScript inserts an implicit semicolon before the expression.

The Fix

Keep the return on the same line, or wrap in parentheses:

// ✅ Same line
const add = (a, b) => a + b;

// ✅ Multi-line with parentheses
const addMulti = (a, b) => (
a + b
);

console.log(add(2, 3)); // 5

💡 Rule: Don’t break immediately after =>.


5. Using the Wrong Function Type in Event Handlers

The Mistake

const button = document.querySelector("button");

button.addEventListener("click", () => {
console.log(this); // ❌ 'this' is Window, not the button
});

Why It Happens

In event handlers, you often want this to point to the element. Arrow functions don’t bind this, so it doesn’t work.

The Fix

Use a traditional function for dynamic this:

button.addEventListener("click", function () {
console.log(this); // ✅ Points to the button
});

💡 Rule: Use traditional functions when you need this bound to DOM elements.


Wrapping It All Up

Here are the 5 common mistakes developers make with arrow vs. traditional functions:

  1. Using arrows as object methods (they lose this).
  2. Using arrows as constructors (not allowed).
  3. Expecting arguments in arrows (use rest instead).
  4. Breaking lines after => (causes unexpected returns).
  5. Using arrows in event handlers where this matters.

Key takeaway:

  • Arrow functions are best for callbacks, utilities, and functional programming.
  • Traditional functions are best for constructors, object methods, and dynamic this use cases.

Call to Action

👉 Have you made one of these arrow vs. function mistakes before? Share your story in the comments 👇.

📤 Send this to a teammate who still confuses the two.
🔖 Bookmark this guide for your next refactor session.

Leave a Reply

Your email address will not be published. Required fields are marked *