> What Happens When a JavaScript File is Run?
1. **Parsing & Compilation Phase (Setup)** * JavaScript **reads** the entire file **before** executing anything. * During this phase, it **hoists** certain declarations: * `function` declarations * `var` declarations (but not their values) * `let` and `const` are *not* hoisted in the same usable way.
2. **Execution Phase (Running line by line)** * Now the code runs **top to bottom**. * Functions already exist in memory (if declared with `function`) * The execution only **enters** a function when it’s **called**
# Example 1: `function` Declaration — Hoisted and Callable Anywhere
sayHello(); // Works even though defined later function sayHello() { console.log("Hello!"); }
> 🔹 The function declaration is **hoisted to the top** automatically, so it’s available before the code reaches the definition.
# Example 2: Function Expression > Not Hoisted the Same Way
sayHello(); // ❌ TypeError: not a function const sayHello = function() { console.log("Hello!"); };
> 🔸 Here, the variable `sayHello` is declared (hoisted), but not **assigned** the function until that line runs — so trying to call it before then fails. Same goes for `let` and `const`.
# Summary Table: Declaration Types
| Type | Hoisted? | Callable Before Line? | Recommended For | | ---------------------- | -------- | --------------------- | ------------------------------------- | | `function foo() {}` | ✅ Yes | ✅ Yes | Top-level or reusable named functions | | `const foo = () => {}` | ❌ No | ❌ No | Anonymous or inline logic | | `let foo = function()` | ❌ No | ❌ No | Scoped function definitions |
# So Where Should You Put Functions?
You **can** put function declarations **anywhere** in the file, even **after** they’re called — *if* you use `function foo()` syntax. But for **clarity and maintainability**, it’s a good practice to: * ✅ Define top-level `function foo()` declarations near the top or in a clearly organized module * ✅ Use `const foo = () => {}` for scoped helper functions, especially in modern JavaScript * ❌ Don’t rely on hoisting for readability — even though it's valid, it confuses others
# Memory Analogy
Think of it like this: * During setup, JavaScript fills in a **map of function names and addresses**. * It knows where each function is, **even before** any line of code runs. * When it hits `sayHello()`, it looks up the function by name and runs it. * But if the function is a variable that holds a function (e.g., `const sayHello = () => {}`), it won’t have a value yet unless that line has already run.