Frontend Development 7 min read

When Not to Use Arrow Functions in JavaScript

This article explains the pitfalls of JavaScript arrow functions, showing when they break object methods, event callbacks, and constructors, and offers clear examples and corrected code to help developers choose between arrow functions and traditional function expressions.

Hujiang Technology
Hujiang Technology
Hujiang Technology
When Not to Use Arrow Functions in JavaScript

Arrow functions introduced in ECMAScript 6 bring concise syntax and lexical this binding, but they are not suitable for every situation. The article demonstrates common misuse cases and provides corrected alternatives.

1. Defining Methods on Objects

Using an arrow function as an object method binds this to the surrounding scope (usually window ), causing errors when the method expects the object itself.

var calculate = {
  array: [1, 2, 3],
  sum: () => {
    console.log(this === window); // => true
    return this.array.reduce((result, item) => result + item);
  }
};
calculate.sum(); // TypeError: Cannot read property 'reduce' of undefined

The fix is to use a regular method definition so that this is bound at call time.

var calculate = {
  array: [1, 2, 3],
  sum() {
    console.log(this === calculate); // => true
    return this.array.reduce((result, item) => result + item);
  }
};
calculate.sum(); // => 6

2. Callback Functions with Dynamic Context

Event listeners rely on this referring to the element that triggered the event. An arrow function captures the outer this (often window ), breaking this behavior.

button.addEventListener('click', () => {
  console.log(this === window); // => true
  this.innerHTML = 'Clicked button';
});

Using a regular function preserves the element context.

button.addEventListener('click', function() {
  console.log(this === button); // => true
  this.innerHTML = 'Clicked button';
});

3. Arrow Functions as Constructors

Arrow functions cannot be used with new because they lack their own this . Attempting to do so throws a TypeError .

var Message = (text) => { this.text = text; };
new Message('Hello'); // TypeError: Message is not a constructor

The correct approach is a traditional function expression.

function Message(text) { this.text = text; }
var helloMessage = new Message('Hello');
console.log(helloMessage.text); // => 'Hello'

4. Ultra‑short Syntax and Readability

While arrow functions can be written in a very terse form, excessive brevity can hurt readability. The example below shows a curried multiply function written both concisely and with clearer syntax.

// Concise version (harder to read)
let double = multiply(2);
double(3); // => 6

// More readable version
function multiply(a, b) {
  if (b === undefined) {
    return function(b) { return a * b; };
  }
  return a * b;
}
let double = multiply(2);
console.log(double(3)); // => 6

5. Summary

Arrow functions are powerful for simplifying code, especially when the lexical this is desired. However, they should be avoided in object method definitions, event callbacks that need a dynamic this , and constructor functions. Balancing brevity with clarity ensures maintainable JavaScript.

JavaScriptProgrammingArrow Functionsfunction contextES6this-binding
Hujiang Technology
Written by

Hujiang Technology

We focus on the real-world challenges developers face, delivering authentic, practical content and a direct platform for technical networking among developers.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.