A Shorter Way to Write Functions
JavaScript Arrow Functions
Arrow functions are JavaScript's compact function syntax. Great for callbacks. They also handle `this` differently — which is usually what you want.
What you'll learn
- Write functions with the `=>` syntax
- Use implicit return for one-liners
- Know that arrow functions don't get their own `this`
The arrow function is a compact function syntax introduced in ES6. The shape:
(params) => expression
// Function declaration:
function double1(n) {
return n * 2;
}
// Function expression:
const double2 = function (n) {
return n * 2;
};
// Arrow function:
const double3 = (n) => n * 2;
console.log(double1(5), double2(5), double3(5)); // 10 10 10 Implicit Return
When the body is a single expression, you can drop the { } and
the return. The expression’s value is returned automatically.
const square = (n) => n * n;
const greet = (name) => `Hello, ${name}!`;
console.log(square(4)); // 16
console.log(greet("Ada")); // "Hello, Ada!" If you need a function body (multiple statements), bring back the
braces — and you must use explicit return.
const describe = (n) => {
if (n > 0) return "positive";
if (n < 0) return "negative";
return "zero";
};
console.log(describe(5)); // "positive" Parameter Quirks
- One parameter — parentheses are optional:
n => n * 2. - Zero or many — parentheses required:
() => 42,(a, b) => a + b.
const noArgs = () => "nothing";
const oneArg = n => n + 1; // parens optional with one arg
const oneArgParens = (n) => n + 1; // also fine, common style
const twoArgs = (a, b) => a + b;
console.log(noArgs(), oneArg(5), twoArgs(2, 3)); Returning an Object Literal
If you want to implicitly return an object literal, wrap it in
parentheses — otherwise {} looks like a function body.
// Wrong — { name } is interpreted as a block!
// const makeUser = (name) => { name };
// Right — parentheses around the object literal:
const makeUser = (name) => ({ name });
console.log(makeUser("Ada")); // { name: 'Ada' } Arrows In Callbacks
This is where arrow functions really shine. Callbacks become one-liners.
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);
console.log(doubled); // [2, 4, 6, 8, 10]
console.log(evens); // [2, 4]
console.log(total); // 15 Arrows Don’t Get Their Own this
This is the most important non-obvious difference between arrows and
regular functions. An arrow function inherits this from where
it was defined.
const timer = {
seconds: 0,
startRegular() {
setInterval(function () {
// `this` here is NOT the timer object — different rules
this.seconds++; // BUG: this is undefined or window
console.log("regular:", this?.seconds);
}, 1000);
},
startArrow() {
setInterval(() => {
this.seconds++; // ✅ this = timer (inherited)
console.log("arrow:", this.seconds);
}, 1000);
},
};
// (We won't actually start the intervals here — just illustrating.) This is what makes arrows great for callbacks inside methods. You
get the surrounding this automatically. We’ll dig into this in
two lessons.
Arrow Limitations
- No own
this, no ownarguments, nonew, nosuper. - Can’t be used as constructors (
newwill throw).
For most cases — callbacks, helpers, short utilities — those limitations are features, not bugs.
Try It Yourself
Exercise
Map with an arrow function
const numbers = [1, 2, 3, 4, 5];
// your code here
💡 Show hint
✅ Show solution
const numbers = [1, 2, 3, 4, 5];
const squared = numbers.map((n) => n * n);
console.log(squared);
Up Next
Where do variables live, and who can see them?
JavaScript Scope →