Okay, so I keep running into this: should I use an arrow function or a function declaration? They both work, but there are some sneaky differences. Let's talk it out.
The Two Approaches
Here’s what I mean. Both of these do the same thing—find a user by id from a list:
Arrow Function Expression
const getUserById = userId => usersFromServer.find(user = user.id === userId);
Function Declaration
function getUserById(userId) {
return usersFromServer.find(user = user.id === userId);
}
Looks basically the same, right? But nah, there's more going on here.
The Real Differences
1. Syntax & Readability
- Arrow functions are slick and short, especially for simple stuff. No need for
return
if it's a one-liner. - Function declarations are a little bulkier but sometimes clearer, especially for bigger functions.
2. Hoisting
- Function declarations? Hoisted. I can use them before they're even written in the code. Magic.
- Arrow functions? Nope. They exist only after the line they're defined on. Try calling one before, and boom—error.
Example:
const usersFromServer = [{id: 1, name: "Jess"}, {id: 2, name: "Jane"}];
console.log(getUserById(1));
function getUserById(id) {
return usersFromServer.find(user => user.id === id);
}
//-> {id: 1, name: 'Jess'} ✅ Works fine
const usersFromServer = [{id: 1, name: "Jess"}, {id: 2, name: "Jane"}];
console.log(getUserById(1));
const getUserById = (id) => usersFromServer.find(user => user.id === id);
//-> Uncaught ReferenceError: getUserById is not defined ❌ Error
3. this
is Weird
- Arrow functions don't have their own
this
. They just borrow it from wherever they're written. - Function declarations? They have their own
this
and change depending on how they're called.
Check this out:
const user = {
id: 1,
getId: () => this.id // ❌ 'this' is NOT the user object
}
console.log(user.getId());
//-> undefined
Now compare:
const user = {
id: 1,
getId() { return this.id } // ✅ 'this' actually refers to the user object
};
console.log(user.getId());
//-> 1
See the problem? Arrow functions don't play nice in objects.
4. When to Use What?
Feature | Arrow Function | Function Declaration |
---|---|---|
Short & clean? | ✅ Yes | ❌ Nope |
Hoisted? | ❌ Nope | ✅ Yep |
Own this ? |
❌ Nope (inherits) | ✅ Yep (changes dynamically) |
Good for objects? | ❌ Nope | ✅ Yep |
So, What's the Verdict?
- Arrow functions = great for quick, simple stuff, especially when
this
doesn't matter (like callbacks). - Function declarations = better when hoisting or
this
matters, like object methods.
Final Thought
Honestly, I just use arrow functions whenever possible—unless this
starts acting up. Then I switch. Simple as that. 🚀
Top comments (4)
You could also have mentioned the "function expression" like this:
The part after the
=
can be a regular function, it's not mandatory to be an arrow function.And you can use it like any function:
This verbosity with JavaScript functions sometimes confuses me.
imho ordenary function are dangerous!
Before ES6 are initiated the class and arow function, then function is the swiss knife.
That can use for function, and for class also.
You can write a class with function:
That why is important to know function is a ghost of our past. And that is the reason why function is handled this a strange way.
Nice explanation of this, but for me I use to prefer function declaration more as those 3 4 liner code gives me better understandably of what's happening and what's that function used for even after it's very simple maths evaluation, and that function keyword gives me clear idea that it's a function