W3docs

JavaScript Function Expressions

JavaScript, a cornerstone of modern web development, offers various ways to define functions, two of which are Function Declarations and Function Expressions.

Introduction to Function Expressions in JavaScript

JavaScript offers several ways to define functions, and two of the most fundamental are function declarations and function expressions. A function expression lets you treat a function like any other value: you can store it in a variable, pass it into another function, or return it from one. Knowing exactly how expressions differ from declarations — especially around hoisting — will save you from a class of confusing bugs.

This page covers the syntax of function expressions, why they behave differently from declarations, named expressions, the most common real-world uses (callbacks, IIFEs, event handlers, async code), and how all of this connects to modern arrow functions.

Function Expressions: Syntax and Usage

What is a Function Expression?

A function expression defines a function as part of a larger expression — typically the right-hand side of an assignment. The function itself is just a value, and the variable you assign it to becomes the way you call it. Here is the most basic form:

javascript— editable

Compare this to a function declaration, which starts with the function keyword as a statement on its own:

javascript— editable

Both produce a callable greet, but they are processed by the engine at different times — which is exactly what the next section is about.

Hoisting: the key difference

Function declarations are hoisted: the engine reads them during the compilation phase, so the function exists before the line where it is written. You can call it earlier in the file. Function expressions are not — the function value is only assigned when execution reaches that line, so calling it too early fails:

javascript— editable
Info

Note: With var, the name greet is hoisted but its value is undefined until the assignment runs, so calling it early throws a TypeError ("greet is not a function"). With let or const the name sits in the temporal dead zone and you get a ReferenceError instead. Either way the rule is the same: define a function expression before you use it.

Characteristics of Function Expressions

  • Anonymous functions: Function expressions are often anonymous — the function has no name of its own and is referred to through the variable.
  • Stored in variables: The function is a value, so it lives in a variable (or array element, object property, etc.).
  • First-class citizens: In JavaScript, functions are first-class values — they can be passed as arguments, returned from other functions, and assigned to variables.
  • Named function expressions: An expression can carry its own name (e.g., let fn = function myFunc() {}). The name is visible only inside the function, which improves stack traces and lets the function call itself.
  • Arrow functions: Modern code often uses arrow functions (() => {}) as a shorter form of expression, though they handle this differently.

Named Function Expressions

Giving an expression an internal name lets the function reference itself reliably — handy for recursion — even if the outer variable is later reassigned:

javascript— editable

Practical Applications of Function Expressions

Callback Functions

The most common use of a function expression is as a callback — a function passed into another function and run later, after some operation finishes. Passing the function inline as an expression keeps the logic right where it is used:

javascript— editable

IIFE (Immediately Invoked Function Expression)

An IIFE is a function expression that runs the moment it is defined. The wrapping parentheses turn the function into an expression, and the trailing () calls it immediately. This was the classic way to create a private scope and avoid leaking variables into the global scope:

javascript— editable
Info

Note: Today, block-scoped let/const and ES modules cover most of what IIFEs were used for, so you will see them less in new code — but they are still common in older libraries and bundled scripts.

Function Expressions vs Function Declarations

Function DeclarationFunction Expression
Syntaxfunction f() {} as a statementlet f = function () {} inside an expression
HoistingFully hoisted — callable before its lineNot callable before the assignment runs
NamingAlways namedOften anonymous (can be named)
Best forTop-level helpers used throughout a fileCallbacks, IIFEs, conditional definitions

A practical rule of thumb: reach for a declaration for a standalone, reusable function, and an expression when the function is a value you are about to pass somewhere or define conditionally.

javascript— editable

Advanced Examples and Use Cases

Event Handling

In the browser, function expressions are the natural way to attach event handlers, since you pass the function directly to addEventListener:

document.getElementById('myButton').addEventListener('click', function () {
  console.log('Button clicked!');
});

Asynchronous Programming

With Promises and async/await, function expressions provide a concise way to pass around units of code. Here a function expression handles each resolved value:

javascript— editable

Conclusion

Mastering Function Expressions in JavaScript is key to writing efficient and maintainable code. Their flexibility, coupled with the power of JavaScript's functional programming capabilities, makes them an indispensable tool in a developer's arsenal.

Remember, the choice between a Function Expression and a Function Declaration depends on the specific requirements of your code and the context in which you are working. Keep practicing and exploring these concepts to deepen your understanding and proficiency in JavaScript.

Practice

Practice
What are the characteristics of function expressions in JavaScript?
What are the characteristics of function expressions in JavaScript?
Was this page helpful?