Skip to main content

When is it better not to use arrow functions?

Arrow functions (=>) are a convenient syntax, but they are not always suitable. There are situations where you need to use a regular function, otherwise the code will behave incorrectly or unpredictably.


1. When you need your own this

Arrow functions have no own this - they inherit it from the outer context. That's why in object methods they often behave unexpectedly.

Bad:

javascript
const user = { name: 'Tim', sayHi: () => { console.log(`Hello, ${this.name}`); // this = undefined } }; user.sayHi(); // "Hello, undefined"

Good:

javascript
const user = { name: 'Tim', sayHi() { console.log(`Hello, ${this.name}`); } }; user.sayHi(); // "Hello, Tim"

2. When the function must be a constructor

Arrow functions cannot be called with new - they have no internal [[Construct]].

Error:

javascript
const Person = (name) => { this.name = name; }; const p = new Person('Tim'); // TypeError: Person is not a constructor

Correct:

javascript
function Person(name) { this.name = name; } const p = new Person('Tim');

3. When you need the arguments object

Arrow functions have no own arguments.

Error:

javascript
const sum = () => { console.log(arguments); // ReferenceError }; sum(1, 2, 3);

Correct:

javascript
function sum() { console.log(arguments); // [1, 2, 3] } sum(1, 2, 3);

(Or use rest parameters: (...args) => {})


4. When the function is used as an event handler (addEventListener)

Sometimes this needs to refer to the element that fired the event.

Won't work:

javascript
button.addEventListener('click', () => { this.classList.add('active'); // this = window or undefined });

Correct:

javascript
button.addEventListener('click', function() { this.classList.add('active'); // this = the button itself });

5. When you need dynamic binding of this (call, apply, bind)

Arrow functions ignore methods like .call() and .bind().

Won't work:

javascript
const greet = () => console.log(this.name); greet.call({ name: 'Tim' }); // undefined

Working variant:

javascript
function greet() { console.log(this.name); } greet.call({ name: 'Tim' }); // Tim

6. When readability matters more than brevity

If a function is complex, long, or contains a lot of logic, an arrow function can hurt readability. It's better to use a regular function with a clear body and name.


Summary - do not use arrow functions if:

SituationWhy
You need your own thisArrow functions have none
You need argumentsArrow functions have none
The function must be a constructor (new)Arrow functions have no [[Construct]]
It's used as a DOM event handlerthis will be lost
You need dynamic binding (call, apply, bind)It's ignored
The function is large and complexReadability suffers

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.