SECTION 1
Historical Context & Motivation
Before functions existed in programming, developers wrote code as long, linear scripts. If you needed the same calculation in three different places, you literally copied and pasted the same lines three times. This made programs enormous, error-prone, and painful to update. The idea of packaging instructions into a named, reusable block—a function—solved this problem and changed the course of software development.
1958 • LISP and First-Class Functions
1972 • C Language Standardizes Function Syntax
1995 • JavaScript Is Born
2015 • ES6 Adds Arrow Functions
So how exactly do you create and use functions in JavaScript? And why does the language give you two different syntaxes—declarations and expressions—for essentially the same idea? Understanding both forms, and the subtle differences between them, is essential for writing clean, organized JavaScript code.
SECTION 2
Core Principles & Definitions
A function is a self-contained block of code designed to perform a specific task. You define it once and then call (invoke) it whenever you need that task performed. Functions accept input through parameters, process that input, and can send back output using a return statement. JavaScript provides two primary ways to create functions: function declarations and function expressions.
Function Declaration
function keyword followed by a name. It is hoisted, meaning JavaScript moves it to the top of its scope, so you can call it before the line where it appears in your code.Function Expression
const or let. It is not hoisted, so it can only be called after the line where it is defined.Parameters vs. Arguments
Return Values
return keyword sends a value back to wherever the function was called. If no return statement exists, the function returns undefined by default.Hoisting
const or let are not.KEY TAKEAWAY
SECTION 3
Visual Explanation — Anatomy of a Function
function keyword, followed by the name, parameters in parentheses, and the body in curly braces. Bottom: A function expression assigns an anonymous function to a variable. Notice the trailing semicolon, since the entire line is a variable assignment statement.The diagram above highlights the structural similarities and differences between the two forms. Both have a set of parameters in parentheses, a function body enclosed in curly braces, and a return statement. The key visual difference is that a declaration starts with function as the very first word, while an expression begins with a variable keyword like const and uses the assignment operator = before the function keyword.
SECTION 4
How It Works — Hoisting and Execution Flow
When JavaScript loads your script, it doesn't simply run code line by line. Instead, the engine performs a two-pass process. During the first pass (the creation phase), JavaScript scans the entire scope for function declarations and variable declarations. Function declarations are fully hoisted—both the name and the function body are moved to the top of the scope in memory. Variable declarations using const or let are recognized but remain in a temporal dead zone until the engine reaches the line where they are assigned.
Declaration: Hoisted and Available Everywhere
Because function declarations are fully hoisted, you can call them before they appear in your source code. For example, the following code works perfectly:
Declaration — Hoisting in Action
const result = greet("Alice");
console.log(result); // "Hello, Alice!"
function greet(name) {
return "Hello, " + name + "!";
}Expression: Must Be Defined First
If you try the same pattern with a function expression, JavaScript throws a ReferenceError because the variable hasn't been initialized yet at the point of the call. You must define the expression before you call it.
Expression — Order Matters
// const result = greet("Alice"); // ❌ ReferenceError!
const greet = function(name) {
return "Hello, " + name + "!";
};
const result = greet("Alice"); // ✓ Works fine hereCalling a Function
Regardless of whether you used a declaration or expression, you call (invoke) a function the same way: write the function name followed by parentheses containing the arguments. The parentheses are what actually execute the function. Without them, you're just referencing the function object itself—not running it. For example, greet is the function object, while greet("Alice") executes the function with the argument "Alice".
SECTION 5
Detailed Comparison — Declarations vs. Expressions
| Feature | Function Declaration | Function Expression |
|---|---|---|
| Syntax starts with | function name() {} | const name = function() {}; |
| Hoisted? | Yes — fully hoisted | No — must be defined first |
| Has a name? | Always named | Can be anonymous or named |
| Used as a value? | Not typically | Yes — can be passed as argument, stored in array, etc. |
| Trailing semicolon? | No | Yes — it's a variable assignment |
| Best for | Top-level utility functions you want available everywhere | Callbacks, closures, and controlled scoping |
Key differences between function declarations and function expressions
In practice, both forms create functions that behave identically once defined. The choice between them often comes down to style and context. Many JavaScript teams prefer const-based expressions because they enforce clear top-to-bottom ordering, while others prefer declarations for the readability of having function names stand out at the start of each line.
SECTION 6
Worked Example — Building a Tip Calculator
Let's build a small tip calculator using both a function declaration and a function expression. We'll write a function that takes a bill amount and a tip percentage, then returns the total amount to pay.
Tip Calculator — Function Declaration
- 1
Step 1 — Define the function
We use thefunctionkeyword, give it a descriptive name, and list two parameters:bill(the subtotal) andtipPercent(the desired tip as a whole number like 20 for 20%).function calculateTotal(bill, tipPercent) { const tip = bill * (tipPercent / 100); return bill + tip; } - 2
Step 2 — Call the function with arguments
We invoke the function by writing its name followed by parentheses containing the actual values (arguments).const total = calculateTotal(50, 20);Inside the function:tip = 50 × (20 / 100) = 10. Return value:50 + 10 = 60 - 3
Step 3 — Use the returned value
The returned value is stored intotal. We can now log it or use it elsewhere.console.log(total); // 60Output: 60 - 4
Step 4 — Rewrite as a function expression
The exact same logic, but now stored in a variable usingconst.const calculateTotal = function(bill, tipPercent) { const tip = bill * (tipPercent / 100); return bill + tip; };Calling it works the same way:calculateTotal(85, 15)returns97.75.tip = 85 × 0.15 = 12.75 → total = 97.75
Pro Tip
calculateTotal, getUserName, formatDate. This makes your code read almost like English and helps other developers (and future you) understand what each function does.SECTION 7
Strengths, Limitations & When to Use Each
| Criterion | Declaration Wins | Expression Wins |
|---|---|---|
| Readability | Stands out clearly; name comes right after the keyword | Groups nicely when assigned alongside other variables |
| Flexibility | Less flexible—always creates a named function in the current scope | Can be anonymous, passed as a callback, or assigned conditionally |
| Order independence | Call it anywhere in its scope thanks to hoisting | Must define before calling—forces logical ordering |
| Debugging | Always shows name in stack traces | Anonymous expressions show as "anonymous" unless named |
| Reassignment safety | Can accidentally be overwritten if another declaration uses the same name | Using const prevents accidental reassignment |
When declarations or expressions have the advantage
CHOOSING THE RIGHT FORM
SECTION 8
Connection to Arrow Functions & Advanced Patterns
Once you're comfortable with declarations and expressions, you'll encounter arrow functions—a shorthand syntax introduced in ES6 (2015). Arrow functions are a type of function expression written with the => symbol. They're especially popular for short, one-line operations and callbacks.
| Style | Syntax Example | Notes |
|---|---|---|
| Declaration | function add(a, b) { return a + b; } | Hoisted; always named |
| Expression | const add = function(a, b) { return a + b; }; | Not hoisted; can be anonymous |
| Arrow (ES6) | const add = (a, b) => a + b; | Shortest form; implicit return for single expressions; different this behavior |
| IIFE | (function() { /* runs immediately */ })(); | Immediately Invoked Function Expression; creates private scope |
Evolution of function syntax in JavaScript
You'll also encounter functions used as callbacks (functions passed as arguments to other functions), closures (functions that remember variables from their outer scope), and higher-order functions (functions that accept other functions as parameters or return them). All of these powerful patterns build directly on the function declaration and expression foundations you've learned in this lesson.
Looking Ahead
this keyword). Master traditional declarations and expressions first—they're the foundation everything else builds on.SECTION 9
Practice Problems
Question 1: CONCEPTUAL
function multiply(x, y) { return x * y; } followed by multiply(3, 7), identify which are parameters and which are arguments.Show answer
x and y are parameters. Arguments are the actual values passed when the function is called. Here, 3 and 7 are arguments. When the function runs, x takes the value 3 and y takes the value 7, producing a return value of 21.Question 2: BASIC CALCULATION
celsiusToFahrenheit that takes a temperature in Celsius and returns it converted to Fahrenheit using the formula F = C × 9/5 + 32. Then call it with the value 25 and state the result.Show answer
function celsiusToFahrenheit(celsius) { return celsius * 9 / 5 + 32; }. Calling celsiusToFahrenheit(25) evaluates to 25 × 9 / 5 + 32 = 45 + 32 = 77. The function returns 77, meaning 25°C equals 77°F. Because this is a declaration, it could be called before or after the function definition in your code due to hoisting.Question 3: INTERMEDIATE
console.log(square(4));
const square = function(n) {
return n * n;
};Show answer
const variable. Variables declared with const are not hoisted in a usable way—they exist in the temporal dead zone until the line where they are assigned. Since console.log(square(4)) appears before the assignment, JavaScript cannot find an initialized square variable. To fix this, you could either move the call below the definition or rewrite it as a function declaration.Question 4: APPLIED
const variable called getLetterGrade that takes a numeric score (0–100) and returns the letter grade: 90–100 = "A", 80–89 = "B", 70–79 = "C", 60–69 = "D", below 60 = "F". Show the function and demonstrate calling it with a score of 84.Show answer
const getLetterGrade = function(score) { if (score >= 90) return "A"; if (score >= 80) return "B"; if (score >= 70) return "C"; if (score >= 60) return "D"; return "F"; };. Calling getLetterGrade(84) returns "B" because 84 is not ≥ 90 (fails first check) but is ≥ 80 (passes second check). The function uses early returns, which means each if exits the function immediately when its condition is true, so no else blocks are needed.Question 5: CRITICAL THINKING
const function expressions because they enforce clear ordering. Write a short paragraph presenting at least one advantage and one disadvantage of each approach, and describe a specific scenario where each form is the better choice.Show answer
const enforce a top-to-bottom reading order that prevents usage before definition, which reduces bugs, and const prevents accidental reassignment of the function name. However, this strict ordering can feel restrictive when you want two functions to call each other (mutual recursion). A good scenario for declarations is a utility file where you want all helper functions available throughout the module. A good scenario for expressions is when passing a function as a callback to addEventListener or setTimeout, where the function is a value being handed to another function.SUMMARY
Lesson Summary
Summary
JavaScript provides two primary ways to create functions. A function declaration begins with the function keyword followed by a name, is hoisted to the top of its scope, and can be called before the line where it appears in your code. A function expression assigns a function (often anonymous) to a variable using const or let, is not hoisted, and must be defined before it is called. Both forms accept parameters (placeholder names) and receive arguments (actual values) when invoked.
You call any function by writing its name followed by parentheses: myFunction(arg1, arg2). The return keyword sends a value back to the caller; without it, the function returns undefined. Use declarations for top-level utility functions and expressions for callbacks, conditional assignments, and enforcing strict code ordering. Mastering both forms prepares you for arrow functions, closures, and higher-order functions—the advanced patterns that make JavaScript so powerful.