Learn the concise arrow function syntax, understand implicit returns, and know when to use arrow functions vs regular functions.
Arrow functions provide a shorter syntax for writing function expressions. They were introduced in ES6 and are now one of the most commonly used features in modern JavaScript.
Basic syntax — parameters in parentheses, arrow, then a block body:
const greet = (name) => {
return 'Hello, ' + name + '!';
};Concise body — if the function body is a single expression, you can omit the curly braces and the return keyword. The expression is implicitly returned:
const double = (x) => x * 2;Single parameter — parentheses are optional when there is exactly one parameter:
const double = x => x * 2;No parameters — use empty parentheses:
const sayHello = () => 'Hello!';Multiple parameters — parentheses are required:
const add = (a, b) => a + b;Arrow functions are especially clean for short callbacks:
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]Understanding when a value is returned is crucial with arrow functions.
Concise body (implicit return): When you omit the curly braces, the single expression is automatically returned:
const square = x => x * x;
console.log(square(5)); // 25Block body (explicit return): When you use curly braces, you must use the return keyword explicitly:
const square = x => {
return x * x;
};A common mistake is using curly braces without return:
const square = x => { x * x }; // Returns undefined!Returning an object literal: Since curly braces are used for the function body, returning an object literal requires wrapping it in parentheses:
// Wrong — JS thinks {} is the function body
const getUser = () => { name: 'Alice' }; // Returns undefined
// Correct — parentheses tell JS it is an expression
const getUser = () => ({ name: 'Alice' });
console.log(getUser()); // { name: 'Alice' }For multiline expressions, you can wrap the entire expression in parentheses:
const getFullName = (first, last) => (
first + ' ' + last
);The most important behavioral difference between arrow functions and regular functions is how they handle the this keyword.
Arrow functions do not have their own this. They inherit this from the enclosing lexical scope (the code that surrounds them).
This makes arrow functions great for callbacks:
const timer = {
seconds: 0,
start() {
// Arrow function inherits 'this' from start()
setInterval(() => {
this.seconds++; // 'this' correctly refers to timer
console.log(this.seconds);
}, 1000);
}
};With a regular function, this would refer to the global object (or undefined in strict mode), not the timer object.
Do NOT use arrow functions as object methods:
const person = {
name: 'Alice',
// Bad — arrow function: 'this' is NOT the person object
greet: () => console.log('Hi, ' + this.name), // undefined
// Good — regular method shorthand
greet() { console.log('Hi, ' + this.name); } // 'Hi, Alice'
};Other limitations:
new keyword).arguments object. Use rest parameters (...args) instead.<div id="output"></div>
<script>
// Regular function
// function add(a, b) { return a + b; }
// Arrow function equivalent
const add = (a, b) => a + b;
// Regular function expression
// const isEven = function(n) { return n % 2 === 0; };
// Arrow function equivalent
const isEven = n => n % 2 === 0;
// Using arrow functions with array methods
const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
const evens = numbers.filter(n => n % 2 === 0);
const doubled = numbers.map(n => n * 2);
const sum = numbers.reduce((acc, n) => acc + n, 0);
const output = document.getElementById('output');
output.innerHTML = `
<p>add(3, 5): ${add(3, 5)}</p>
<p>isEven(4): ${isEven(4)}</p>
<p>isEven(7): ${isEven(7)}</p>
<p>Evens: [${evens}]</p>
<p>Doubled: [${doubled}]</p>
<p>Sum: ${sum}</p>
`;
</script>What does `const add = (a, b) => a + b; add(2, 3)` return?