Question
I'm maintaining an existing JavaScript codebase and noticed that functions are defined in two different ways. I want to understand whether there is a meaningful difference between them, and when each style should be used.
The two patterns are:
var functionOne = function() {
// Some code
};
and:
function functionTwo() {
// Some code
}
What are the reasons for using these two different approaches? What are the advantages and disadvantages of each? Is there anything you can do with one that you cannot do with the other?
Short Answer
By the end of this page, you will understand the difference between function declarations and function expressions in JavaScript. You will learn how they behave with hoisting, where they are commonly used, how they affect readability and flexibility, and how to choose the right one in real code.
Concept
In JavaScript, both of these forms create functions, but they are not processed in exactly the same way.
function greet() {
console.log("Hello");
}
This is a function declaration.
var greet = function() {
console.log("Hello");
};
This is a function expression assigned to a variable.
Core difference
A function declaration defines a named function directly. A function expression creates a function as a value, then stores that value in a variable.
That matters because in JavaScript, functions are first-class values. This means a function can be:
- stored in a variable
- passed to another function
- returned from another function
- used as part of an object or array
Why the difference matters
The biggest practical difference is hoisting.
Function declaration hoisting
Function declarations are hoisted with their full definition, so they can be called before they appear in the code.
Mental Model
Think of a function declaration like a named tool that is placed in your toolbox before you start working.
A function expression is more like building a tool and then putting it into a labeled box.
- With a function declaration, JavaScript prepares the tool early, so you can use it anywhere in that scope.
- With a function expression, JavaScript first creates the box (
var functionOne), but the tool is not placed inside until execution reaches that line.
So:
- declaration = the tool is ready early
- expression = the label exists first, the tool arrives later
This mental model helps explain why one can be called before its definition and the other usually cannot.
Syntax and Examples
Function declaration
function add(a, b) {
return a + b;
}
console.log(add(2, 3)); // 5
This creates a named function called add.
Function expression
var add = function(a, b) {
return a + b;
};
console.log(add(2, 3)); // 5
This creates a function and stores it in the variable add.
Named function expression
A function expression can also have its own internal name.
var factorial = function fact(n) {
if (n <= 1) {
return ;
}
n * (n - );
};
.(());
Step by Step Execution
Consider this example:
console.log(square(4));
function square(n) {
return n * n;
}
What happens
- JavaScript scans the scope.
- It finds the function declaration
square. - It hoists the full function definition.
console.log(square(4))runs.square(4)returns16.
Now compare that with:
console.log(square(4));
var square = function(n) {
return n * n;
};
What happens here
- JavaScript scans the scope.
- It finds
var squareand hoists only the variable declaration. - At this point,
squareisundefined.
Real World Use Cases
When function declarations are useful
1. Main reusable functions
If a function is an important part of the module, a declaration is often clear and readable.
function validateUser(user) {
return user && user.email;
}
2. Organizing helper functions
Some developers like putting high-level logic at the top and helper declarations below, relying on hoisting.
startApp();
function startApp() {
loadConfig();
}
function loadConfig() {
console.log("Loading config...");
}
When function expressions are useful
1. Callbacks
JavaScript APIs often expect functions as arguments.
[1, 2, 3].map(function(n) {
return n * 2;
});
2. Conditional assignment
Real Codebase Usage
In real projects, both styles appear, but they are usually used with intent.
Common patterns
Top-level declarations for core logic
Developers often use function declarations for named operations that are central to a file.
function parseResponse(data) {
return JSON.parse(data);
}
function handleRequest(data) {
const result = parseResponse(data);
return result;
}
This makes stack traces readable and keeps main functions easy to find.
Function expressions for callbacks and local behavior
items.filter(function(item) {
return item.active;
});
This is common when the function is only needed in one place.
Guard clauses with named functions
Function declarations often pair well with readable validation flows.
function saveUser(user) {
if (!user) ;
(!user.) ;
.();
}
Common Mistakes
1. Calling a function expression before assignment
Broken code:
sayHello();
var sayHello = function() {
console.log("Hello");
};
Problem:
sayHello is undefined at the time of the call.
Fix:
var sayHello = function() {
console.log("Hello");
};
sayHello();
2. Assuming both forms hoist the same way
Many beginners think all functions can be called before they appear.
Broken assumption:
console.log(getTotal(2, 3));
var getTotal = function(a, b) {
return a + b;
};
Avoid this by remembering:
Comparisons
| Feature | Function Declaration | Function Expression |
|---|---|---|
| Basic syntax | function name() {} | var name = function() {} |
| Hoisted fully | Yes | No |
| Can be called before definition | Yes | Usually no |
| Stored in a variable | Not primarily | Yes |
| Good for callbacks | Possible, but less common inline | Very common |
| Can be anonymous | No | Yes |
| Conditional definition | Less natural | More natural |
| Readability for top-level helpers | Often very good |
Cheat Sheet
Quick reference
Function declaration
function greet() {
console.log("Hello");
}
- hoisted with full function body
- can be called before definition
- good for reusable named functions
Function expression
const greet = function() {
console.log("Hello");
};
- function is created as a value
- assignment happens at runtime
- cannot be called before assignment
- useful for callbacks and dynamic assignment
Hoisting rule
hello(); // works
function hello() {}
hello(); // error
var hello = function() {};
Modern recommendation
FAQ
Is var fn = function() {} the same as function fn() {}?
No. Both create functions, but they differ in hoisting and how they are defined. A function declaration is available earlier in the scope, while a function expression assigned to var is not callable until assignment happens.
Which is better in JavaScript: function declaration or function expression?
Neither is always better. Function declarations are great for main named functions. Function expressions are better when a function is being passed, stored, or chosen dynamically.
Why can function declarations be called before they are written?
Because JavaScript hoists the full function declaration during scope setup.
Why does a function expression with var fail before its definition?
Because only the variable declaration is hoisted. The variable exists, but its value is undefined until the assignment line runs.
Can a function expression have a name?
Yes.
const fn = function helper() {
return "ok";
};
This can help with recursion and debugging.
Should I still use var for function expressions?
Usually no. In modern JavaScript, or is preferred because block scoping is safer and clearer.
Mini Project
Description
Build a small utility that formats messages differently depending on the user's role. This project demonstrates when a function expression is useful for dynamic assignment and when a function declaration is useful for stable reusable helpers.
Goal
Create a script that selects one formatting function for admins and another for regular users, then prints a formatted message.
Requirements
- Create a reusable function declaration to validate that a username is present.
- Use a function expression assigned to a variable to choose different formatting behavior.
- Print a formatted message for at least two different user roles.
- Prevent formatting if the username is missing.
Keep learning
Related questions
Deep Cloning Objects in JavaScript: Methods, Trade-offs, and Best Practices
Learn how to deep clone objects in JavaScript, compare structuredClone, JSON methods, and recursive approaches with examples.
Get Screen, Page, and Browser Window Size in JavaScript
Learn how to get screen size, viewport size, page size, and scroll position in JavaScript across major browsers with clear examples.
How JavaScript Closures Work: A Beginner-Friendly Guide
Learn how JavaScript closures work with simple explanations, examples, common mistakes, and practical use cases for real code.