DocsHub
Functions

Function Expression

Learn what function expressions are, how they differ from function declarations, and when to use them.

Function Expression

In the previous topic we declared functions like this:

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

But in JavaScript, functions are values — just like numbers, strings, and booleans. You can store them in variables, pass them around, and use them wherever a value is expected.

A function expression is simply a function stored in a variable.

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

greet(); // Hello!

The function has no name of its own — it lives inside the variable greet. You call it the same way — greet() — but it is defined differently.


Syntax

const functionName = function() {
  // code to run
};

Notice the semicolon at the end — ;. Because this is a variable assignment, it ends like any other variable declaration.

With parameters and a return value:

const add = function(a, b) {
  return a + b;
};

console.log(add(10, 5)); // 15

Function Declaration vs Function Expression

They look similar but behave differently in one important way — hoisting.

// ✅ Function declaration — can be called before it is defined
sayHello(); // Hello!

function sayHello() {
  console.log("Hello!");
}
// ❌ Function expression — cannot be called before it is defined
greet(); // ReferenceError: Cannot access 'greet' before initialization

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

Function declarations are hoisted — JavaScript moves them to the top before running the code. Function expressions are not — the variable exists but the function value is not assigned until that line runs.

We cover hoisting in full detail in its own topic. For now just remember — with function expressions, define first, call after.

Function DeclarationFunction Expression
Syntaxfunction name() {}const name = function() {}
Hoisted?✅ Yes❌ No
Has its own name?✅ YesNot required
Ends with ;?❌ No✅ Yes

Named Function Expression

A function expression can have its own internal name — but that name is only accessible inside the function itself.

const factorial = function calculate(n) {
  if (n <= 1) return 1;
  return n * calculate(n - 1); // can use 'calculate' inside
};

console.log(factorial(5)); // 120
console.log(typeof calculate); // ReferenceError — not accessible outside

The internal name calculate is useful for recursion — calling the function from within itself. Outside the function only factorial exists.


Functions as Values

This is where function expressions become truly powerful. Because the function is stored in a variable — it is a value. And values can be passed around.

Storing in an object

const calculator = {
  add: function(a, b) { return a + b; },
  subtract: function(a, b) { return a - b; },
  multiply: function(a, b) { return a * b; },
};

console.log(calculator.add(10, 5));      // 15
console.log(calculator.subtract(10, 5)); // 5
console.log(calculator.multiply(10, 5)); // 50

Passing a function to another function

function runTwice(fn) {
  fn();
  fn();
}

const sayHi = function() {
  console.log("Hi!");
};

runTwice(sayHi);
// Hi!
// Hi!

A function passed to another function as an argument is called a callback. This is one of the most important patterns in JavaScript — used everywhere from array methods to event listeners to async code.

Returning a function from a function

function createMultiplier(multiplier) {
  return function(number) {
    return number * multiplier;
  };
}

const double = createMultiplier(2);
const triple = createMultiplier(3);

console.log(double(5));  // 10
console.log(triple(5));  // 15

createMultiplier returns a new function every time it is called. double and triple are function expressions born at runtime with different behavior baked in. This pattern is called a closure — covered in depth in the Advanced section.


A Real Example — Flexible Greeting

function buildGreeting(timeOfDay) {
  if (timeOfDay === "morning") {
    return function(name) {
      console.log(`Good morning, ${name}! Hope your day goes well.`);
    };
  } else if (timeOfDay === "evening") {
    return function(name) {
      console.log(`Good evening, ${name}! Hope you had a great day.`);
    };
  } else {
    return function(name) {
      console.log(`Hello, ${name}!`);
    };
  }
}

const morningGreet = buildGreeting("morning");
const eveningGreet = buildGreeting("evening");

morningGreet("Ali");  // Good morning, Ali! Hope your day goes well.
eveningGreet("Sara"); // Good evening, Sara! Hope you had a great day.

buildGreeting returns a different function depending on the time of day. Each returned function is a function expression created and returned on the fly.


When to Use Function Expression vs Declaration

Both are valid — the choice depends on the situation.

// Use declaration for main, named, reusable functions
function calculateTotal(price, tax) {
  return price + tax;
}

// Use expression when passing functions around
const numbers = [3, 1, 4, 1, 5];
numbers.sort(function(a, b) {
  return a - b;
});

// Use expression when storing functions in objects
const validator = {
  isEmail: function(value) {
    return value.includes("@");
  },
  isEmpty: function(value) {
    return value.trim() === "";
  }
};
SituationUse
Top level reusable utility functionDeclaration
Function passed as a callbackExpression
Function stored in an objectExpression
Function returned from another functionExpression
You need to call it before defining itDeclaration

In modern JavaScript, arrow functions have largely replaced function expressions for callbacks and inline functions. We cover arrow functions in the next topic — and you will see why they are preferred.


Summary

  • A function expression stores a function in a variable — const fn = function() {}
  • Unlike declarations, function expressions are not hoisted — define before calling
  • Always end with a semicolon since it is a variable assignment
  • Functions are values — they can be stored in objects, passed as arguments, and returned from other functions
  • A function passed to another function is called a callback
  • Use declarations for top level reusable functions, use expressions when passing functions around or storing them in objects

On this page