A Shorter Way to Write a Function
Arrow functions are JavaScript's terser syntax for defining a function. They showed up in ES2015 and are now the default style for small, inline functions — especially callbacks passed to array methods, promise handlers, and event listeners.
The shape is: parameters, then =>, then the body.
Same result as the classic form:
const add = function (a, b) {
return a + b;
};
Less typing is nice, but the real reasons to care about arrow functions are the implicit return and how they treat this. Both are coming up.
Implicit Return
If the body is a single expression, you can drop the braces and the return. The expression's value is returned automatically:
This is where arrow functions shine — one-line transforms read like math:
The moment you need more than one statement, you're back to braces and an explicit return:
Forgetting the return inside braces is the most common arrow-function mistake. x => { x * 2 } returns undefined — the braces turn the body into a block, and the expression inside is thrown away.
Parameter Parentheses
With exactly one parameter, the parentheses are optional:
With zero, two, or more parameters, you need them:
Some teams prefer always-parentheses for consistency. Both styles are fine — pick one and stick with it.
Returning an Object Literal
Here's a gotcha. If you try to implicitly return an object, the braces look like a function body:
That prints undefined. JavaScript reads { name: name } as a block with a labeled statement, not an object literal. Wrap the object in parentheses to force it to be an expression:
The () around { ... } is the fix. File it away — you'll hit this within the first week of writing arrow functions.
Lexical this
The real reason arrow functions exist isn't the shorter syntax. It's that they don't have their own this. They inherit it from the surrounding scope.
To see why that matters, consider a regular function used as a callback:
Inside the function () { ... } passed to setInterval, this is not counter. Regular functions get their own this based on how they're called, and setInterval calls the callback with this as undefined (in strict mode) or the global object.
An arrow function keeps the this of the enclosing method:
Inside the arrow function, this is still counter because the arrow doesn't introduce its own this. Before arrow functions, people worked around this with const self = this; or .bind(this). Those patterns still work but are rarely needed now.
What Arrow Functions Don't Have
The lexical-this rule is part of a larger pattern: arrow functions skip several things that regular functions have.
- No own
this— inherited from the enclosing scope. - No
argumentsobject — use rest parameters (...args) instead. - No
new— you can't use an arrow function as a constructor. - No
prototypeproperty — follows from the no-newrule.
...args gives you the same "accept any number of arguments" capability that arguments did, with the bonus that it's a real array. The new Greeter(...) call throws because arrow functions aren't constructors.
When Not to Use an Arrow Function
Arrow functions are the default for callbacks, but they're the wrong choice in a few spots:
Object methods defined with arrow syntax don't get this bound to the object — they inherit it from wherever the object literal was written (usually the module or global scope). Use the shorthand method syntax (greet() { ... }) for methods.
Same idea for class prototype methods, event-handler methods that need this to refer to the element, and any function you plan to call with new. A regular function is the correct tool there.
A Quick Rule of Thumb
- Short callback, one expression? Arrow function.
- Need
thisto stay bound to the outer scope? Arrow function. - Defining a method on an object or class prototype? Regular function (or shorthand method).
- Writing a constructor? Regular function, or better yet, a
class.
You'll see both styles in any real JavaScript codebase. Knowing which one fits takes a few weeks of reading other people's code — after that, the choice becomes automatic.
Next: Parameters and Defaults
Arrow functions and regular functions share the same parameter features — default values, rest parameters, destructured arguments, and more. That's the next page, and it applies to every function form you've seen so far.
Frequently Asked Questions
What is an arrow function in JavaScript?
An arrow function is a shorter way to write a function, using the => syntax. const add = (a, b) => a + b; is an arrow function that takes two arguments and returns their sum. Besides the terser syntax, arrow functions don't bind their own this, arguments, or super — they inherit them from the surrounding scope.
What's the difference between arrow functions and regular functions?
Regular functions declared with function have their own this, their own arguments object, and can be used as constructors with new. Arrow functions have none of those — they inherit this from wherever they're defined. Arrow functions also can't be hoisted the way function declarations are.
When should I use an arrow function?
Reach for arrow functions for short callbacks (arr.map(x => x * 2)), and anywhere you want this to stay bound to the enclosing scope — like inside a class method that passes a handler to setTimeout or an event listener. Use a regular function for methods on objects, constructors, and standalone top-level functions.