Skip to main content

Command Palette

Search for a command to run...

Function Declaration vs Function Expression

Updated
Function Declaration vs Function Expression

In the previous blog, we learned what functions are and why they are important. By now, you understand how functions help you write reusable and structured code.

But there is something subtle that most beginners ignore.

Not all functions in JavaScript are created the same way.

At first glance, writing a function might seem straightforward. But the way you define a function actually affects how JavaScript executes your code.

This is where the difference between a function declaration and a function expression comes in.

And this is not just theory. This difference shows up in interviews, debugging, and real-world applications.


Two Ways to Create Functions

In JavaScript, there are mainly two ways to define a function.

1. Function Declaration

function greet() {
 console.log("Hello"); 
}

This is the most common and straightforward way.

2. Function Expression

const greet = function() {
 console.log("Hello"); 
};

Here, the function is assigned to a variable.

At this point, both look similar. If you call them, they behave the same.

greet();

So, where is the difference?

The difference starts when you look at how JavaScript executes this code.


The Real Difference: Hoisting

To understand the difference, recall what we discussed earlier about hoisting.

Let’s test function declaration:

greet();
function greet(){
    console.log("Hello");
}

This works perfectly.

Even though the function is written after the call, JavaScript still executes it.

Why?

Because function declarations are fully hoisted.


What Does Fully Hoisted Mean?

It means both the function name and its entire definition are moved to the top of the scope during execution.

So internally, JavaScript treats it like this:

function greet() { 
    console.log("Hello"); 
}
greet();

That’s why it works.


Now, try the Same with a function expression.

greet(); // Error
const greet = function() { 
    console.log("Hello"); 
};

This throws an error.

Why?

Because function expressions are not hoisted the same way.

What Actually Happens Internally

When you write:

const greet = function() {
    console.log("Hello"); 
};

JavaScript treats it like a variable.

So it becomes:

const greet; // hoisted but not initialized
greet(); // ReferenceError (TDZ)
greet = function() { 
    console.log("Hello"); 
};

Since const is in the Temporal Dead Zone, you cannot access it before initialisation.

This is the key difference.

Important Summary

  • Function declarations are fully hoisted.

  • Function expressions behave like variables.

  • Variables declared with let and const are in TDZ

This is why one works before definition and the other does not.

Another Subtle Difference: Naming

Function declarations must have a name.

funtion greet(){}

Function expressions can be anonymous.

const greet = function (){};

You can also give them a name:

const greet = function sayHello(){};

But that name is only accessible inside the function.


Functions as Values

This is where function expressions become powerful.

In JavaScript, functions are first-class citizens.

That means:

  • You can store them in variables.

  • Pass them as arguments.

  • Return them from other functions.

function execute(fn) {
    fn();
}
execute(function(){
    console.log("Hello");
});

You cannot easily do this with function declarations in the same flexible way.


Conditional Function Creation

This is another place where function expressions shine.

let greet;
if (true) {
    greet = function(){
        console.log("Hello");
    };
}
greet();

You cannot do this cleanly with function declarations.


Arrow Functions and Expressions

Arrow functions are actually a type of function expression.

const greet = () => {
    console.log("Hello");
};

So everything we said about function expressions applies to arrow functions as well.


When Should You Use What?

Use function declarations when:

  • You want simple, reusable functions.

  • You need hoisting

  • The function is defined at the top level

Use function expressions when:

  • You want more control.

  • You are working with callbacks.

  • You need conditional logic.

  • You want to use arrow functions.


Common Mistakes

1. Calling function expressions before definition

sayHi(); //Error
const sayHi = function (){};

2. Confusing hoisting behavior

Just because something is hoisted does not mean it is usable.

3. Overusing function declarations

In modern JavaScript, function expressions are used more often, especially in real-world applications.


Real-World Example

function calculate(a, b, operation) {
    return operation(a, b); 
}

const add = function(x, y) { 
    return x + y; 
};

const multiply = (x, y) => x * y;

console.log(calculate(5, 3, add)); 
console.log(calculate(5, 3, multiply));

Here:

  • We are passing functions as values.

  • Using both expressions and arrow functions

This is how real applications are built.


Final Thought

At first, function declarations and function expressions may seem like two ways of doing the same thing.

But once you understand how JavaScript treats them differently, you start writing better and more predictable code.

This difference is small on the surface, but very important underneath.

Understanding this properly will make upcoming topics like callbacks, closures, and async JavaScript much easier.

JavaScript Fundamentals (The Absolute Basics )

Part 4 of 5

“Learn JavaScript from scratch with this beginner-friendly series covering variables, functions, arrays, objects, and core fundamentals with practical examples.”

Up next

Arrow Functions in JavaScript

A Simpler Way to Write Functions