Arrow functions provide a concise syntax for writing functions. They are now the dominant way to write functions in modern JavaScript code, especially for callbacks and short utilities.
Arrow function syntax
The basic form replaces the function keyword with an arrow:
const greet = (name) => {
return `Hello, ${name}!`;
};
For a single parameter, the parentheses are optional:
const greet = name => {
return `Hello, ${name}!`;
};
For no parameters, use empty parentheses:
const sayHello = () => {
console.log("Hello!");
};
Implicit return
When the body is a single expression, you can omit the braces and the return keyword. The expression is returned automatically:
const double = (n) => n * 2;
double(5); // 10
This is called an implicit return. It makes short functions very readable:
const add = (a, b) => a + b;
const isFirst = (arr) => arr.length > 0;
const fullName = (user) => `${user.firstName} ${user.lastName}`;
Returning object literals
Implicit return has one gotcha. Curly braces after the arrow are interpreted as a function body, not an object literal. Wrap the object in parentheses:
// Wrong — braces are treated as the function body, not an object
const makeUser = (name) => { name: name, active: true }; // syntax error
// Correct — parentheses force expression context
const makeUser = (name) => ({ name, active: true });
How arrow functions differ from regular functions
Arrow functions are not just a shorter syntax. They behave differently in one important way: they do not have their own this binding.
A regular function’s this depends on how it is called. An arrow function’s this is inherited from the surrounding scope — it is the same this that exists where the arrow function is defined.
const counter = {
count: 0,
increment() {
// regular function as a callback — `this` would be wrong here
setTimeout(() => {
this.count++; // arrow inherits `this` from increment's scope
}, 100);
},
};
In practice, this means:
- use arrow functions for callbacks where you want to keep the outer
this - use regular functions for methods that need their own
this(object methods, class methods, event handlers wherethisshould be the element)
Arrow functions also cannot be used as constructors:
const User = (name) => { this.name = name; };
new User("Ada"); // TypeError — arrow functions cannot be constructors
When to use arrow functions
Use arrow functions:
- for short, single-expression utilities
const toCelsius = (f) => (f - 32) * (5 / 9); - for callbacks passed to array methods
const names = users.map((u) => u.name); - for callbacks passed to
setTimeout,Promise.then, event listenersbutton.addEventListener("click", () => { console.log("clicked"); });
Use regular functions:
- for object methods that need
thisconst counter = { count: 0, increment() { this.count++; }, // regular function }; - for class methods
- when you need the
argumentsobject (arrow functions do not have it) - for named top-level functions where you prefer the declaration form
Arrow functions in practice
Most modern codebases use arrow functions for the majority of functions and reserve regular function syntax for methods and specific cases where this matters:
// Top-level utility — arrow with implicit return
const formatDate = (date) => date.toISOString().split("T")[0];
// Callback — arrow with implicit return
const activeUsers = users.filter((u) => u.active);
// Event handler — arrow with block body
button.addEventListener("click", (event) => {
event.preventDefault();
console.log("Button clicked:", event.target.textContent);
});
What to carry forward
- arrow functions use
(params) => expressionsyntax - single-expression bodies return implicitly — no braces or
returnneeded - wrap object literals in parentheses when using implicit return:
() => ({ key: value }) - arrow functions inherit
thisfrom their surrounding scope — they do not have their ownthis - arrow functions cannot be constructors and do not have an
argumentsobject - use arrow functions for callbacks and short utilities; use regular functions for methods
Arrow functions make code shorter and more predictable. The next lesson covers parameters in more depth — defaults and rest parameters.