Arrow Functions vs. Normal Functions in JavaScript 2024: The Definitive Comparison Guide


Introduction

JavaScript offers two main ways to define functions: traditional (normal) functions and arrow functions. While both serve the purpose of defining reusable blocks of code, there are fundamental differences in their behavior, especially regarding scope, syntax, and the this keyword.

Let’s explore the differences, the use cases for each, and tackle some common interview questions around this topic.


1. What is the Syntax Difference Between Arrow and Normal Functions?

Normal Function Syntax:

function greet(name) {
    return `Hello, ${name}!`;
}

Arrow Function Syntax:

const greet = (name) => `Hello, ${name}!`;

Key Differences:

  • Normal functions can be declared using the function keyword.
  • Arrow functions use the => syntax, which is shorter and cleaner.

2. How Does this Behave Differently in Arrow and Normal Functions?

One of the most significant differences is how the this keyword is handled.

Normal Function:

const person = {
    name: 'Alice',
    greet: function() {
        console.log(`Hello, my name is ${this.name}`);
    }
};
person.greet(); // Output: "Hello, my name is Alice"

Arrow Function:

const person = {
    name: 'Alice',
    greet: () => {
        console.log(`Hello, my name is ${this.name}`);
    }
};
person.greet(); // Output: "Hello, my name is undefined"

Explanation:

  • In normal functions, this refers to the object that invoked the function (in this case, person).
  • In arrow functions, this is lexically bound, meaning it refers to the this value from the surrounding scope (outside of the greet method). As a result, this.name is undefined here.

Interview Insight: Arrow functions don’t create their own this context, making them unsuitable for object methods that rely on this.


3. Can Arrow Functions Be Used as Constructors?

Normal Functions:

function Person(name) {
    this.name = name;
}
const alice = new Person('Alice');
console.log(alice.name); // Output: "Alice"

Arrow Functions:

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

Explanation:

  • Normal functions can be used as constructors (with the new keyword) to create objects.
  • Arrow functions cannot be used as constructors because they do not have a [[Construct]] method.

Interview Insight: Arrow functions are not suitable for creating object instances.


4. How Do Arrow and Normal Functions Handle Arguments?

Normal Functions:

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

Arrow Functions:

const sum = () => {
    console.log(arguments);
};
sum(1, 2, 3); // ReferenceError: arguments is not defined

Explanation:

  • Normal functions have access to the arguments object, which contains all passed arguments.
  • Arrow functions do not have their own arguments object. You can use rest parameters (...args) instead:
  const sum = (...args) => {
      console.log(args);
  };
  sum(1, 2, 3); // Output: [1, 2, 3]

Interview Insight: The absence of arguments in arrow functions makes them less flexible when dealing with unknown or variable numbers of arguments.


5. How Are Arrow Functions Used in Callbacks?

Normal Functions as Callbacks:

setTimeout(function() {
    console.log('Normal function after 1 second');
}, 1000);

Arrow Functions as Callbacks:

setTimeout(() => {
    console.log('Arrow function after 1 second');
}, 1000);

Explanation:

  • Arrow functions are popular in callbacks because of their concise syntax and lexical this binding.
  • They’re ideal for inline functions where this doesn’t need to change.

Interview Insight: Arrow functions simplify callbacks, especially in array methods like map, filter, and reduce.


6. Can Arrow Functions Be Used as Methods in Objects?

Using Normal Functions:

const obj = {
    value: 10,
    getValue: function() {
        return this.value;
    }
};
console.log(obj.getValue()); // Output: 10

Using Arrow Functions:

const obj = {
    value: 10,
    getValue: () => this.value
};
console.log(obj.getValue()); // Output: undefined

Explanation:

  • Normal functions correctly bind this to the object.
  • Arrow functions don’t work well as methods since this is not bound to the object but to the surrounding scope.

Interview Insight: Avoid using arrow functions as methods in objects.


7. Performance: When to Use Arrow Functions vs. Normal Functions?

  • Arrow Functions are generally more performant when used in callbacks or functional programming scenarios, as they’re shorter and don’t create their own this or arguments.
  • Normal Functions are better for methods, constructors, or situations where dynamic this binding is required.

Interview Insight: Use arrow functions for simplicity and normal functions for versatility.


8. Can Arrow Functions Have Default Parameters?

Yes, both arrow and normal functions support default parameters.

Normal Function:

function multiply(a = 2, b = 3) {
    return a * b;
}
console.log(multiply()); // Output: 6

Arrow Function:

const multiply = (a = 2, b = 3) => a * b;
console.log(multiply()); // Output: 6

What is ‘this’ in Arrow function defined inside class vs Object

Arrow functions in JavaScript do not have their own this context. Instead, they inherit this from the enclosing lexical context at the time they are defined. This behavior is consistent whether the arrow function is defined in an object or a class. However, the perceived difference arises from the context in which the arrow function is defined and called.

const taxi = {
  name: "kalipili",
  book: function () {
    console.log("Booked", this);
  },
  cancel: () => {
    console.log("Canceled", this);
  },
};

taxi.book();   // "Booked", { name: "kalipili", book: [Function: book], cancel: [Function: cancel] }
taxi.cancel(); // "Canceled", window (or global object in Node.js)

In the above example:

  • book is a regular function, so this refers to the taxi object when taxi.book() is called.
  • cancel is an arrow function, so this refers to the global object (or undefined in strict mode) because it inherits this from the lexical scope where taxi is defined, which is the global scope.

Example in a Class

class Taxi {

class Taxi {
  constructor(name) {
    this.name = name;
  }

  book() {
    console.log("Booked", this);
  }

  cancel = () => {
    console.log("Canceled", this);
  };
}

const myTaxi = new Taxi("kalipili");

myTaxi.book();   // "Booked", Taxi { name: "kalipili", cancel: [Function: cancel] }
myTaxi.cancel(); // "Canceled", Taxi { name: "kalipili", cancel: [Function: cancel] }  
  • book is a regular method, so this refers to the instance of the Taxi class when myTaxi.book() is called.
  • cancel is an arrow function, but it is defined as a property of the class instance. Therefore, this refers to the instance of the Taxi class when myTaxi.cancel() is called because it inherits this from the constructor’s lexical scope.

Key Differences

  1. Object Context:
    • Arrow functions in objects inherit this from the global scope (or the enclosing function scope if defined inside a function).
    • Regular functions in objects have their this set to the object when called as a method.
  2. Class Context:
    • Arrow functions defined as class properties inherit this from the class instance’s constructor.
    • Regular methods in classes have their this set to the class instance when called as a method.

Additional Essential JavaScript Interview Questions on Various Topics

Top Javascript Books to Read

Conclusion: When to Use Arrow Functions vs. Normal Functions

FeatureArrow FunctionsNormal Functions
SyntaxShort and conciseLonger, more verbose
this ContextLexically boundDynamically bound
Constructors (new)Not supportedSupported
arguments ObjectNot availableAvailable
Best Use CasesCallbacks, functional programmingMethods, constructors, variable this context

Key Interview Takeaway: Understand when to use arrow functions vs. normal functions based on this behavior, syntax, and requirements for arguments or constructor functions.


This comprehensive overview of arrow functions vs. normal functions should help clarify their differences and provide valuable insights for JavaScript interview preparation.

3 thoughts on “Arrow Functions vs. Normal Functions in JavaScript 2024: The Definitive Comparison Guide”

Leave a Comment