Arrow Functions in JavaScript
Arrow functions are a shorter way to write functions. They also behave differently from regular functions when it comes to the this keyword, which is the most important thing to understand about them.
Basic syntax
Instead of the function keyword, you use an arrow (=>).
// Regular function
function add(a, b) {
return a + b;
}
// Arrow function: same thing, shorter
const add = (a, b) => {
return a + b;
};
console.log(add(3, 4)); // 7
Implicit return
If the function body is a single expression, you can drop the curly braces and the return keyword. The expression is returned automatically.
const add = (a, b) => a + b;
const double = n => n * 2;
const greet = name => `Hello, ${name}!`;
console.log(add(3, 4)); // 7
console.log(double(5)); // 10
console.log(greet('Anna')); // Hello, Anna!
To return an object literal implicitly, wrap it in parentheses so JavaScript does not confuse the braces with a function body.
const makeUser = (name, age) => ({ name, age });
console.log(makeUser('Anna', 28)); // { name: 'Anna', age: 28 }
Parameter rules
- No parameters: use empty parentheses.
- One parameter: parentheses are optional, but many style guides keep them for consistency.
- Two or more parameters: parentheses are required.
const greetWorld = () => 'Hello, World!';
const double = n => n * 2;
const add = (a, b) => a + b;
The this keyword difference
This is the most important distinction between arrow functions and regular functions.
Regular functions have their own this. The value of this depends on how the function is called. This can be unpredictable.
Arrow functions do not have their own this. They inherit this from the surrounding code where they were defined. This is called lexical this.
Here is a practical example. Suppose you have a Timer class that counts up every second.
function Timer() {
this.seconds = 0;
// Regular function loses the reference to 'this'
setInterval(function() {
this.seconds++; // 'this' here refers to the global object, not the Timer
console.log(this.seconds); // NaN (not what we want)
}, 1000);
}
With an arrow function, this refers to the Timer instance because arrow functions inherit this from the surrounding scope.
function Timer() {
this.seconds = 0;
// Arrow function inherits 'this' from the Timer function
setInterval(() => {
this.seconds++;
console.log(this.seconds); // 1, 2, 3 ... (correct)
}, 1000);
}
const t = new Timer();
When to use arrow functions
Arrow functions work well for:
Callbacks and array methods. This is where you will use them most.
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
const total = numbers.reduce((sum, n) => sum + n, 0);
Short utility functions.
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
const isEven = n => n % 2 === 0;
Callbacks where you want to preserve this from the outer context (timers, promises, class methods).
When not to use arrow functions
Object methods that need this to refer to the object.
const user = {
name: 'Anna',
// Arrow function: 'this' does NOT refer to user
greetArrow: () => {
console.log(`Hello, ${this.name}`); // undefined
},
// Regular function: 'this' refers to user
greetRegular() {
console.log(`Hello, ${this.name}`); // Hello, Anna
},
};
user.greetArrow(); // Hello, undefined
user.greetRegular(); // Hello, Anna
Constructor functions. Arrow functions cannot be used with new.
const Person = (name) => {
this.name = name;
};
const anna = new Person('Anna'); // TypeError: Person is not a constructor
Use a regular function or a class instead.
Common mistakes
Using an arrow function as an object method and being surprised this is wrong:
const counter = {
count: 0,
// Wrong: arrow function, 'this' does not refer to counter
increment: () => {
this.count++; // undefined.count (error or NaN)
},
};
Fix it with a regular method:
const counter = {
count: 0,
increment() {
this.count++; // 'this' correctly refers to counter
},
};
FAQ
When should I use an arrow function vs a regular function?
Use an arrow function for callbacks, array methods, and any short inline function where you do not need the function to have its own this. Use a regular function declaration or expression for object methods, constructors, and any situation where you need this to refer to the object that called the function.
See the Functions page for declarations, expressions, rest parameters, and closures.