DocsHub
Functions

Arrow Functions

Learn how to write shorter, cleaner functions using arrow function syntax in JavaScript.

Arrow Functions

Arrow functions were introduced in ES6 as a shorter, cleaner way to write functions. They are now the most common way to write functions in modern JavaScript — especially for callbacks and inline functions.

// Function expression
const add = function(a, b) {
  return a + b;
};

// Arrow function — same thing, less code
const add = (a, b) => {
  return a + b;
};

Same behavior, cleaner syntax. But arrow functions go even further — they have shorthand rules that can make them even shorter depending on what they do.


Basic Syntax

const functionName = (parameters) => {
  // code
};

The function keyword is gone. Instead you have the parameters, then => (the arrow), then the function body.


Shorthand Rules

Arrow functions have two shorthand forms that make them even more concise.

Single parameter — drop the parentheses

When there is exactly one parameter, you can remove the parentheses around it.

// With parentheses
const greet = (name) => {
  console.log(`Hello, ${name}!`);
};

// Without parentheses — one parameter
const greet = name => {
  console.log(`Hello, ${name}!`);
};

Zero parameters or two or more parameters always need parentheses:

const sayHi = () => console.log("Hi!");         // no params — need ()
const add = (a, b) => a + b;                    // two params — need ()

Single expression body — implicit return

When the function body is just one expression that returns a value, you can remove the curly braces and the return keyword. The value is returned automatically.

// Full version
const double = (n) => {
  return n * 2;
};

// Implicit return — one line, no braces, no return
const double = n => n * 2;

console.log(double(5)); // 10

The value after => is automatically returned. This is called an implicit return.

Returning an object — wrap in parentheses

If you want to implicitly return an object, wrap it in parentheses — otherwise JavaScript thinks the curly braces are the function body.

// ❌ Wrong — JS reads {} as the function body, not an object
const getUser = () => { name: "Ali", age: 22 };

// ✅ Correct — parentheses tell JS this is an object
const getUser = () => ({ name: "Ali", age: 22 });

console.log(getUser()); // { name: 'Ali', age: 22 }

Arrow Functions in Practice

Arrow functions shine most when used as callbacks — functions passed to other functions.

With array methods

const numbers = [1, 2, 3, 4, 5];

// map — transform every item
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// filter — keep items that pass a condition
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4]

// reduce — combine all items into one value
const total = numbers.reduce((sum, n) => sum + n, 0);
console.log(total); // 15

Compare how this looks with regular function expressions:

// Without arrow functions — verbose
const doubled = numbers.map(function(n) {
  return n * 2;
});

// With arrow functions — clean
const doubled = numbers.map(n => n * 2);

The arrow function version is so much easier to read that it has become the standard.

With setTimeout

// Without arrow function
setTimeout(function() {
  console.log("Done!");
}, 1000);

// With arrow function
setTimeout(() => console.log("Done!"), 1000);

The Important Difference — this

Arrow functions are not just shorter syntax — they behave differently from regular functions in one important way. They do not have their own this.

In a regular function, this refers to whatever object called the function. In an arrow function, this is inherited from the surrounding code where the arrow function was defined.

const timer = {
  seconds: 0,

  start: function() {
    // Regular function — 'this' is lost inside setInterval
    setInterval(function() {
      this.seconds++; // ❌ 'this' is undefined here
      console.log(this.seconds);
    }, 1000);
  }
};
const timer = {
  seconds: 0,

  start: function() {
    // Arrow function — 'this' is inherited from start()
    setInterval(() => {
      this.seconds++; // ✅ 'this' correctly refers to timer
      console.log(this.seconds);
    }, 1000);
  }
};

timer.start(); // 1, 2, 3, 4...

The arrow function picks up this from start() — which correctly points to the timer object. A regular function inside setInterval would lose the reference to timer.

The this keyword is covered in full detail in the Advanced section. For now just remember — when you need this inside a callback, use an arrow function.


When Not to Use Arrow Functions

Arrow functions are not always the right choice. Because they don't have their own this, avoid them in these situations:

Object methods

const user = {
  name: "Ali",

  // ❌ Arrow function — this does not refer to user
  greet: () => {
    console.log(`Hello, ${this.name}`); // undefined
  },

  // ✅ Regular function — this correctly refers to user
  greet: function() {
    console.log(`Hello, ${this.name}`); // Hello, Ali
  }
};

Constructor functions

// ❌ Arrow functions cannot be used as constructors
const Person = (name) => {
  this.name = name;
};

const ali = new Person("Ali"); // TypeError: Person is not a constructor

All Three Function Styles Side by Side

// Function declaration
function multiply(a, b) {
  return a * b;
}

// Function expression
const multiply = function(a, b) {
  return a * b;
};

// Arrow function
const multiply = (a, b) => a * b;

All three do exactly the same thing. In modern JavaScript, the arrow function version is the most common for simple operations like this.


A Real Example — Student Results

const students = [
  { name: "Ali",  score: 88 },
  { name: "Sara", score: 45 },
  { name: "Zara", score: 92 },
  { name: "Omar", score: 61 },
  { name: "Hassan", score: 37 },
];

// Filter passing students (score >= 50)
const passed = students.filter(student => student.score >= 50);

// Get their names
const names = passed.map(student => student.name);

// Calculate average score of passing students
const average = passed.reduce((sum, student) => sum + student.score, 0) / passed.length;

console.log("Passed:", names);
// Passed: [ 'Ali', 'Zara', 'Omar' ]

console.log(`Average score: ${average}`);
// Average score: 80.33...

Three operations, three arrow functions, clean and readable from top to bottom. This chaining style with arrow functions is how modern JavaScript is written.


Summary

  • Arrow functions are a shorter way to write functions — const fn = () => {}
  • Single parameter — parentheses are optional: name => {}
  • Single expression body — curly braces and return are optional: n => n * 2
  • Returning an object implicitly — wrap in parentheses: () => ({ key: value })
  • Arrow functions do not have their own this — they inherit it from the surrounding scope
  • Use arrow functions for callbacks, array methods, and inline functions
  • Avoid arrow functions for object methods and constructor functions

On this page