AceDevHub
Control Flow & FunctionsFree

Functions: Declarations and Expressions

Create reusable logic with function declarations, expressions, arrow functions, parameters, and return values.

BeginnerFreeFunctions

Functions are the primary unit of reuse in JavaScript. They can be declared, assigned to variables, passed as callbacks, and returned from other functions. This lesson covers the three syntax forms you will see in every codebase and the rules that differ between them — hoisting, this binding, and the arguments object.

Functions package behavior

A function packages parameters, local variables, and return behavior. JavaScript treats functions as first-class values — you can store them in variables, pass them to setTimeout, and return them from factories. That design enables callbacks, middleware, event handlers, and React components. The syntax you choose (declaration, expression, arrow) affects hoisting and this binding even when the body is identical.

Function declaration — hoisted name

Function declarations are hoisted with their name — the engine registers the whole function before executing the line where it appears. That is why you can call double(5) above its declaration in the same scope. Declarations create a readable stack trace name automatically and belong at module level or as named helpers inside functions.

declaration.js
Loading editor…
Outputconsole
10
Hello, Sangam!
Welcome, Sangam!

Function expression — value assigned to variable

Function expressions assign an anonymous or named function to a variable. const fn = function() {} is not hoisted — accessing fn before the line throws because of let/const temporal dead zone. Named function expressions (const f = function inner() {}) expose inner inside the function for recursion while keeping the outer binding const. Export const in modules is the modern public API pattern.

expression.js
Loading editor…
Outputconsole
9
120

Arrow functions — concise syntax

Arrow functions shorten syntax and lexically capture this from the surrounding scope — they do not have their own this, arguments, or new.target. That makes them ideal for .map callbacks and React event handlers when you want outer this. They are wrong for object methods that need dynamic this and cannot be used as constructors (no new Arrow()).

arrow.js
Loading editor…
Outputconsole
36
5
100
{ x: 1, y: 2 }

Rest parameters — flexible arity

Rest parameters (...rest) replace the old arguments pseudo-array with a real array — cleaner and works naturally with destructuring. Default parameters apply when the argument is undefined (not when it is null unless you design for that). Combining defaults and rest covers most HTTP handler and utility signatures without the legacy arguments object.

rest-params.js
Loading editor…
Outputconsole
10
[API] Request started
[API] User authenticated

Return values and early exit

return ends function execution immediately and sends a value to the caller. Functions without return yield undefined implicitly — often a bug if you forgot return in an async chain. Early return keeps functions short: validate, handle edge cases, then return the computed result without wrapping the main logic in else.

return.js
Loading editor…
Outputconsole
{ name: 'B', role: 'admin' }
undefined
  1. 1Declarations hoist; const expressions do not
  2. 2Arrow functions: concise, lexical this, no arguments object
  3. 3Default params activate for undefined — not for null
  4. 4Rest ...args collects remaining parameters as an array
  5. 5Next lesson: scope, closures, hoisting, and the temporal dead zone