Function Statement vs Function Expression in JavaScript
Function statements and expressions look similar but hoist differently. Here is the difference.
Function Statement vs Function Expression in JavaScript
There are two main ways to define a function in JavaScript. They look similar but behave differently due to hoisting.
Function Statement (Declaration)
function greet(name) { return `Hello, ${name}`; } `` - Hoisted with the full body. Can be called before the declaration line. - The name is bound in the enclosing scope. ### Function Expression ```js const greet = function (name) { return `Hello, ${name}`; }; `` - The function is assigned to a variable. The variable is hoisted (`var` as `undefined`, `let`/`const` in TDZ), not the function. - Must be declared before calling. ### The Hoisting Difference ```js // Function statement: works foo(); // "hello" function foo() { console.log("hello"); } // Function expression: fails bar(); // TypeError: bar is not a function var bar = function () { console.log("hello"); }; // Function expression with const: fails differently baz(); // ReferenceError (TDZ) const baz = () => console.log("hello"); `` ### Named Function Expression ```js const greet = function sayHi(name) { return `Hello, ${name}`; }; `` `sayHi` is only visible inside the function (useful for recursion and stack traces). Outside, you must use `greet`. ### Arrow Function (Always an Expression) ```js const greet = (name) => `Hello, ${name}`; `` Arrows are always expressions. They do not have their own `this` or `arguments`. ### When to Use Each - **Function declarations**: for top-level helpers you want callable from anywhere in the file (hoisting is useful). - **Function expressions (with `const`)**: for everything else, especially when you want predictable declaration-before-use behavior. - **Arrow functions**: for short callbacks and when you want lexical `this`. ### Best Practice For consistency and to avoid hoisting surprises, many teams default to `const` arrow functions everywhere and only use function declarations when hoisting is genuinely needed. ### The Takeaway Function statements are hoisted with their full body and can be called early. Function expressions are assigned to variables and must be declared before use. Use declarations for top-level helpers and `const` expressions (often arrows) for the rest.
A function statement (declaration) is hoisted with its full body, so it can be called before the line. A function expression is assigned to a variable, which is hoisted (undefined with var, TDZ with let/const) but the function body is only assigned at the line.
No. With var, calling it early throws TypeError because the variable is undefined. With let or const, it throws ReferenceError because the variable is in the Temporal Dead Zone.
Because function declarations are hoisted with their entire body during the memory allocation phase. The engine stores the full function in memory before any code runs, so calling it before the line works.
Use declarations for top-level helpers you want callable from anywhere (hoisting is useful). Use const function expressions (often arrows) for everything else, to enforce declare-before-use and avoid hoisting surprises.
Always an expression. Arrow functions are always assigned to a variable. They are hoisted as variables, not as functions, and they do not have their own this or arguments.
Ready to master React completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master React
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

