Web

JS Function Declarations vs Expressions: Differences & Use Cases

Discover key differences between JavaScript function declarations and function expressions. Explore hoisting, pros, cons, var function() {} vs function name() {}, and real-world use cases for better coding.

1 answer 8 views

What are the differences between function declarations and function expressions in JavaScript, including their pros, cons, and use cases? Specifically, what are the reasons for using var functionOne = function() {} versus function functionTwo() {}, and what can be done with one method that can’t be done with the other?

JavaScript function declarations like function functionTwo() {} get hoisted to the top of their scope, so you can call them before they’re physically written in code. Function expressions, such as var functionOne = function() {}, aren’t hoisted that way—only the variable is, leaving the function undefined until execution hits the assignment. Declarations suit reusable utilities anywhere in scope; expressions excel at callbacks, one-offs, and avoiding namespace clutter.


Contents


JavaScript Function Declarations

Picture this: you’re midway through a script, and bam—you need to invoke a function that’s defined lines later. No sweat with declarations. A JavaScript function declaration looks like function functionTwo() { console.log('Hoisted!'); }. The JS engine reads the entire script first, hoists the whole thing—name and body—to the top of its scope during compilation.

Why does this matter? Hoisting means functionTwo(); works even if called before the line where it’s written. FreeCodeCamp nails it: declarations load into memory before execution starts. Same goes for MDN docs—they emphasize how this makes functions available throughout the block, function, or global scope.

But here’s a quirk. Nest them in an if-statement? Like if (true) { function sneaky() {} }. Old browsers hoist it anyway, potentially to the outer scope. Messy, right? Modern strict mode helps, but it trips up beginners.

javascript
// This works—hoisting in action
sayHello(); // "Hello!"

function sayHello() {
 console.log("Hello!");
}

Declarations always have a name, aiding recursion or debugging stacks. They’re your go-to for core app logic.


Function Expressions in JavaScript

Flip the script. Function expressions assign a function to a variable: var functionOne = function() { console.log('Not hoisted'); };. The variable functionOne hoists (as undefined), but the assignment waits until runtime. Call it early? Error city: TypeError: functionOne is not a function.

JavaScript.info breaks it down: expressions arise in assignment contexts, not standalone statements. GeeksforGeeks adds they can be anonymous—no name required—perfect for quick jobs.

You can name them too: var namedOne = function inner() {}; (name’s just for internal use, like recursion). And don’t sleep on arrow functions—they’re expressions by nature: const arrow = () => {};.

javascript
// This fails
greet(); // TypeError!

var greet = function() {
 console.log("Hi there!");
};

Expressions shine in dynamic spots. Ever passed a sorter to array.sort()? That’s an expression, often anonymous.


Key Differences Between Them

Aspect Function Declaration Function Expression
Syntax function name() {} var/const/let name = function() {}
Hoisting Full hoist (name + body) Variable hoists as undefined
Timing Compile phase Runtime assignment
Naming Always named Optional (anonymous OK)
Scope Block/function/global Determined by variable (let/const block-scoped)

Stack Overflow consensus: hoisting’s the star difference. Declarations process pre-execution; expressions wait. Sentry.io clarifies var functionName = function() {} evaluates line-by-line.

What about const or let? Same expression rules apply—safer scoping than var. No hoisting surprises there.

Confused on conditionals? Declarations hoist regardless; expressions let you pick based on logic. Game-changer.


Pros and Cons of Function Declarations

Pros:

  • Call anytime in scope. Freedom!
  • Named for stack traces—debugging dreams.
  • Reusable globally without reassignment fuss.

Cons:

  • Pollutes scope. Global utils() everywhere? Recipe for conflicts.
  • Conditional hoisting weirdness in legacy browsers.
  • Can’t assign conditionally without hacks.

Gomakethings warns of namespace bloat. Still, for bootstrapping apps, they’re clutch.


Pros and Cons of Function Expressions

Pros:

  • Scoped tight—const keeps 'em local.
  • Anonymous for throwaways, no name pollution.
  • Conditional definition: let fn = condition ? fnA : fnB;.
  • IIFEs: (function() { /* private world */ })();.

Cons:

  • Must define before use. Order matters.
  • Anonymous? Stack traces say “anonymous”—hunt time.
  • var hoists undefined—gotcha for newbies.

Readwriteexercise loves their intuitive flow: define, then call. W3tutorials echoes flexibility.


Real-World Use Cases

Declarations rock for:

  • Main modules: event handlers, APIs.
  • Libraries: function fetchData() {}—use early.
  • Recursion: self-reference easy.

Like function factorial(n) { return n ? n * factorial(n-1) : 1; }.

Expressions fit:

  • Callbacks: fetch(url).then(function(data) { ... });.
  • Modules: IIFEs for privates pre-ES6.
  • Higher-order: array.map(function(item) { return item * 2; });.
  • Conditionals: API mocks in tests.

FreeCodeCamp’s second piece suggests declarations for globals, expressions for args. Spot on.

Modern twist? Arrows as expressions: const handler = (e) => e.preventDefault();. Concise.


Unique Capabilities: What One Does That the Other Can’t

Declarations: Invoke before code line. Pure magic, but risky in blocks. Can’t define conditionally without duplication.

Expressions: True conditionals. if (isDev) { var mock = function() { return fakeData; }; }. No hoist leaks. IIFEs create instant scopes—var result = (function() { var private = 42; return private * 2; })();. Declarations can’t self-invoke that slick.

Pass anonymously: setTimeout(function() { alert('Tick!'); }, 1000);. No extra name. Devdotun highlights control.

Bottom line: Use function functionTwo() {} for always-available helpers. var functionOne = function() {} for flexible, scoped power.


Sources

  1. FreeCodeCamp: Function Declaration vs Function Expression
  2. MDN: function expression
  3. FreeCodeCamp: When to use declarations vs expressions
  4. JavaScript.info: Function expressions
  5. GeeksforGeeks: Difference between declaration and expression
  6. Stack Overflow: Expression vs declaration
  7. Sentry.io: var function vs function
  8. Gomakethings: Expressions vs declarations
  9. Readwriteexercise: Declarations vs expressions
  10. W3tutorials: var functionName vs function
  11. Devdotun: Understanding differences

Conclusion

Master function declarations for hoisted reliability in core logic, but lean on function expressions for modern scoping, callbacks, and conditionals—especially with const or arrows. The var functionOne = function() {} style gives you runtime control and IIFE magic that declarations can’t match without workarounds, while function functionTwo() {} delivers anytime access. Pick based on needs: avoid global mess, embrace flexibility, and your JS will flow smoother. Test in console—hoisting hits different once you see it.

Authors
Verified by moderation
Moderation
JS Function Declarations vs Expressions: Differences & Use Cases