When to not use arrow functions in JavaScript

📖 2 min read

Arrow functions are a more concise alternative to the traditional function expression but they aren't appropriate everywhere.

Let's check out some examples of times you would not want to use arrow functions.

Scenario 1. Callback functions that require dynamic context.

Callback functions that require dynamic context, such as the element clicked, are not good candidates for arrow functions because you are unable to change the pre-defined context of this.

js
const button = document.querySelectorAll( '.cta-button' );
button.addEventListener( 'click', () => {
this.classList.toggle( 'selected' ); // `this`refers to the Window. ☚ī¸
} );

Using a regular function allows the value of this to change based on the context of the target element.

js
const button = document.querySelectorAll( '.cta-button' );
button.addEventListener( 'click', function() {
this.classList.toggle( 'selected' ); // `this`refers to the button! 🎉🎉🎉
} );

Scenario 2. Functions that use the arguments object.

Arrow functions do not bind the global arguments object.

js
const logUser = () => {
console.log(arguments[0]); // Uncaught ReferenceError: arguments is not defined 😕
}
logUser( 'Kevin' );

But with a regular function, you have access to the global arguments object.

js
function logUser() {
console.log(arguments[0]); // Kevin
console.log(arguments[1]); // Langley
}
logUser( 'Kevin', 'Langley' );

Scenario 3. Prototype Methods

js
function User(firstName, lastName) {
this.name = `${firstName} ${lastName}`;
}
User.prototype.sayHello = () => {
return `Hello, ${this.name}`;
}
const me = new User( 'Kevin', 'Langley' );
me.sayHello(); // Hello,

The this value in the sayHello method references the global object and not the User object that it is trying to access.

Instead, write your prototype methods the old fashioned way.

js
function User(firstName, lastName) {
this.name = `${firstName} ${lastName}`;
}
User.prototype.sayHello = function() {
return `Hello, ${this.name}`;
}
const me = new User( 'Kevin', 'Langley' );
me.sayHello(); // Hello, Kevin Langley

Scenario 4. Object methods

js
const user = {
name: 'Kevin Langley',
sayHello: () => `Hello, ${this.name}`;
}
user.sayHello(); // Hello,

The this value in the sayHello method references the global object and not the User object that it is trying to access.

Instead, write your prototype methods the old fashioned way.

js
const user = {
name: 'Kevin Langley',
sayHello() {
return `Hello, ${this.name}`;
}
}
user.sayHello(); // Hello, Kevin Langley