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)); // 10The 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); // 15Compare 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 constructorAll 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
returnare 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