Appearance
breaking down the two different types of functions
Which is better?
Arrow functions or function declarations?
In this article we are going to break down the two different types of functions.
Async Function Declaration
For example:
async function example() {
// ...
}
This is an async function declaration.
Function declarations are hoisted, which means its definition is available throughout its scope. It is also a named function (its name is accessible within the function body for recursion and debugging).
Async Arrow Function Expression
For example:
const example = async () => {
// ...
}
This is an async arrow function expression.
Function expressions are not hoisted, it’s assigned to a variable (example) and only available after the assignment.
Arrow functions have a lexically bound this and no own arguments object, among other differences from regular functions.
Which is better?
The Winner: Function Expressions
const example = async () => {
// ...
}
✅ Why it's better (in modern JS):
Consistent scoping
Arrow functions don’t rebind this, arguments, or super. That makes them predictable in callbacks or component methods (like in Vue or React).
Immutable by default
Using const
when necessary prevents reassignment — safer, less footguns.
Clear async intent
async
keyword is directly visible at the function definition site. Readability wins.
Function expression > declaration (in modules)
Hoisting with function declarations (async function example() {}
) can be misleading in modern module systems where temporal dead zone rules apply.
When function declarations win
Function declarations win over function expressions in JavaScript in terms of hoisting—they are fully hoisted to the top of their scope (i.e., available before they're defined in the code), while function expressions are not.