Suggest an editImprove this articleRefine the answer for “Function declaration vs function expression”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**A function declaration (`function greet() {}`) is hoisted in full, so you can call it above the line where it is declared; a function expression (`const greet = function () {}`) is created only when the assignment actually runs, so a call before that line throws.** A declaration is always named and enters the scope when the scope is initialised, while an expression is part of a larger expression, may be anonymous or named, and is handy for callbacks and event handlers. ```javascript greet(); // works: the declaration is fully hoisted function greet() { console.log('Hello!'); } bye(); // ReferenceError: Cannot access 'bye' before initialization const bye = function () { console.log('Bye!'); }; ``` **Key point:** a declaration is created up front, when the scope is initialised, an expression is created when its assignment line runs.Shown above the full answer for quick recall.Answer (EN)Image**A function declaration declares the function up front, so it is available anywhere in its scope, even above the line where it is written, while a function expression creates the function only when the assignment line runs.** Both produce an ordinary function; the difference is when it appears in the scope and whether it must have a name. ## Theory ### TL;DR - `function greet() {}` is a declaration: it is hoisted together with its body, so you can call it anywhere in its scope. - `const greet = function () {}` is an expression: only the variable is hoisted, the function appears after the assignment. - Calling an expression before the assignment throws `ReferenceError` for `const` and `let` (temporal dead zone) or `TypeError: greet is not a function` for `var`. - A declaration is always named, an expression may be anonymous or named. - Use declarations for the main functions of a module, and expressions or arrow functions for callbacks, handlers and parts of expressions. ### Quick example ```javascript // --- Function Declaration --- sayHi(); // works function sayHi() { console.log('Hi!'); } // --- Function Expression --- sayBye(); // error: the variable is not initialised yet const sayBye = function () { console.log('Bye!'); }; ``` ### Function declaration A declaration starts a statement with the `function` keyword: ```javascript function sayHello() { console.log('Hello!'); } ``` Characteristics: - **Hoisting.** The function is available above its declaration: the engine creates it, body included, while initialising the scope. - The function name is fixed and available in the current scope. - You can call it anywhere in the file or block, even above the declaration. ```javascript greet(); // works, although the function is declared below function greet() { console.log('Hello!'); } ``` Result: ```javascript Hello! ``` ### Function expression A function expression is a function on the right-hand side of an expression, most often an assignment: ```javascript const sayHello = function () { console.log('Hello!'); }; ``` or the arrow version: ```javascript const sayHello = () => console.log('Hello!'); ``` Characteristics: - **Not hoisted like a declaration.** The variable is created, but the function inside it is unavailable until initialisation. - It can be **anonymous** (no name) or **named** (`const f = function inner() {}`, where `inner` is visible only inside the function itself and shows up nicely in stack traces). - It is an expression, so it can be called **only after** the assignment. ```javascript sayHello(); // error: the function does not exist yet const sayHello = function () { console.log('Hello!'); }; ``` ### Key differences | Property | Function Declaration | Function Expression | | --- | --- | --- | | **Hoisting** | Yes, available before the declaration | No, unavailable before the assignment | | **When it is created** | When the scope is initialised | While the line is executed | | **Can it be called before the declaration?** | Yes | No | | **Function name** | Required, a declaration is always named | May be anonymous or named | | **Good for** | Core functions needed everywhere | Local ones, passed as arguments, callbacks | | **Usage example** | `function sum(a, b) {}` | `const sum = (a, b) => {}` | ### What to choose - **Function declaration** when the function is used widely across the module and it is convenient to call it anywhere, for example top-level helpers. - **Function expression or arrow function** when the function is local: an event handler, a callback, an argument to `map`/`filter`, part of an expression, or a value returned from another function. Short version to remember: > `function declaration` is created up front (hoisting). > `function expression` is created at the moment of execution. ### Common mistakes - **Assuming expressions are hoisted too.** Only the variable declaration is hoisted. With `var` it holds `undefined`, so the call throws `TypeError: sayBye is not a function`; with `const` and `let` the variable is in the temporal dead zone, so the call throws `ReferenceError: Cannot access 'sayBye' before initialization`. - **Relying on declaration hoisting inside a block.** In strict mode a function declared inside an `if` or a loop is scoped to that block and does not exist outside it. - **Making callbacks anonymous for no reason.** A named expression (`const handler = function handler() {}`) gives a meaningful stack trace while debugging. - **Confusing arrow functions with `function` expressions.** An arrow function is also an expression, but it has no own `this` or `arguments` and cannot be used as a constructor. - **Declaring the same declaration twice.** The later declaration silently overrides the earlier one, and the bug only shows up at runtime.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.