Ad – 728Γ—90
βš™οΈ Functions

JavaScript Functions – Declarations, Expressions, and Hoisting

Functions are the building blocks of JavaScript programs β€” reusable chunks of code that do one job well. This lesson covers every way to define a function, how hoisting works, IIFE, and why JavaScript treats functions as first-class citizens.

⏱️ 20 min read 🎯 Beginner πŸ“… Updated 2026

Function Declaration

A function declaration uses the function keyword followed by a name, parameters, and a body. It is the most traditional way to define a function in JavaScript.

JavaScript
// Declare a function
function greet(name) {
  return "Hello, " + name + "!";
}

// Call (invoke) it
console.log(greet("Alice")); // Hello, Alice!
console.log(greet("Bob"));   // Hello, Bob!

// Function with no parameters
function sayHi() {
  console.log("Hi there!");
}
sayHi();
β–Ά Output
Hello, Alice! Hello, Bob! Hi there!

Naming Conventions

  • Use camelCase: calculateTotal, getUserName
  • Start with a verb that describes what the function does: get, set, calculate, validate, create, handle
  • Be specific: getUserAge is better than getAge or doStuff
  • Boolean-returning functions: prefix with is, has, can: isValid, hasPermission

Function Expression

A function expression assigns a function to a variable. The function may be named or anonymous.

JavaScript
// Anonymous function expression
const square = function(n) {
  return n * n;
};
console.log(square(5)); // 25

// Named function expression (name only visible inside body)
const factorial = function fact(n) {
  if (n <= 1) return 1;
  return n * fact(n - 1); // Can call fact() recursively here
};
console.log(factorial(5)); // 120

// Passed directly as an argument
setTimeout(function() {
  console.log("Runs after 0ms");
}, 0);
β–Ά Output
25 120 Runs after 0ms

Function Hoisting

JavaScript hoists function declarations to the top of their scope before execution. This means you can call a declared function before it appears in the source code. Function expressions are NOT hoisted in the same way.

JavaScript
// Call BEFORE the declaration β€” works because of hoisting
console.log(add(2, 3)); // 5

function add(a, b) {
  return a + b;
}

// Function expression β€” NOT hoisted
try {
  console.log(multiply(2, 3)); // Error!
} catch (e) {
  console.log(e.message); // Cannot access 'multiply' before initialization
}

const multiply = function(a, b) {
  return a * b;
};
β–Ά Output
5 Cannot access 'multiply' before initialization
ℹ️
Hoisting Under the Hood

During the creation phase, the JavaScript engine scans the code and registers all function declarations (and var declarations) before running any code. Only function declarations are fully hoisted β€” their name and body. var declarations are hoisted but initialized to undefined. let/const are hoisted but not initialized (Temporal Dead Zone).

IIFE – Immediately Invoked Function Expression

An IIFE runs immediately after it is defined. It creates a private scope and is used to avoid polluting the global namespace.

JavaScript
// Basic IIFE
(function() {
  const secret = "I'm private!";
  console.log("IIFE ran: " + secret);
})();

// Arrow function IIFE
(() => {
  console.log("Arrow IIFE ran");
})();

// IIFE with parameters
const result = (function(a, b) {
  return a + b;
})(10, 20);
console.log("IIFE result: " + result); // 30

// Variables inside IIFE don't leak out
try {
  console.log(secret); // ReferenceError
} catch(e) {
  console.log("Cannot access 'secret' outside IIFE");
}
β–Ά Output
IIFE ran: I'm private! Arrow IIFE ran IIFE result: 30 Cannot access 'secret' outside IIFE

Functions as First-Class Citizens

In JavaScript, functions are values β€” they can be assigned to variables, stored in arrays/objects, passed as arguments, and returned from other functions.

JavaScript
// Assign to variable
const greet = function(name) { return "Hi, " + name; };

// Store in object (method)
const math = {
  add: function(a, b) { return a + b; },
  subtract: (a, b) => a - b,
};
console.log(math.add(3, 4));      // 7
console.log(math.subtract(10, 3)); // 7

// Store in array
const operations = [
  (x) => x * 2,
  (x) => x + 10,
  (x) => x ** 2,
];
console.log(operations[0](5)); // 10
console.log(operations[1](5)); // 15
console.log(operations[2](5)); // 25

// Pass as argument (callback)
function applyTwice(fn, value) {
  return fn(fn(value));
}
console.log(applyTwice(x => x * 2, 3)); // 12
β–Ά Output
7 7 10 15 25 12

Functions vs Methods

A method is simply a function stored as a property of an object. The distinction is about context and calling syntax, not underlying mechanics.

JavaScript
// Standalone function
function describe(name, age) {
  return name + " is " + age + " years old.";
}

// Same logic as a method
const person = {
  name: "Alice",
  age: 30,
  describe: function() {
    return this.name + " is " + this.age + " years old.";
  }
};

console.log(describe("Bob", 25));  // Bob is 25 years old.
console.log(person.describe());    // Alice is 30 years old.
β–Ά Output
Bob is 25 years old. Alice is 30 years old.

Default Parameters (ES6+)

JavaScript
// Default parameter values
function greetUser(name = "Stranger", greeting = "Hello") {
  return greeting + ", " + name + "!";
}

console.log(greetUser());               // Hello, Stranger!
console.log(greetUser("Alice"));        // Hello, Alice!
console.log(greetUser("Bob", "Hey"));  // Hey, Bob!

// Default can reference earlier params
function createBadge(name, role = "member", prefix = role.toUpperCase()) {
  return `[${prefix}] ${name}`;
}
console.log(createBadge("Alice", "admin")); // [ADMIN] Alice
β–Ά Output
Hello, Stranger! Hello, Alice! Hey, Bob! [ADMIN] Alice

Rest Parameters – Quick Intro

The ...rest syntax collects any number of extra arguments into an array. Full details are in the next lesson.

JavaScript
function sum(...numbers) {
  return numbers.reduce((total, n) => total + n, 0);
}

console.log(sum(1, 2, 3));         // 6
console.log(sum(1, 2, 3, 4, 5));   // 15
console.log(sum(10));              // 10
β–Ά Output
6 15 10

Recursion – A Brief Introduction

A function that calls itself is recursive. Every recursion needs a base case to stop, otherwise it creates infinite recursion and a stack overflow.

JavaScript
function factorial(n) {
  if (n <= 1) return 1;   // Base case
  return n * factorial(n - 1); // Recursive case
}

console.log(factorial(5)); // 120 (5*4*3*2*1)
console.log(factorial(0)); // 1
β–Ά Output
120 1
Ad – 336Γ—280

πŸ‹οΈ Practical Exercise

Create these functions:

  1. A declared function celsiusToFahrenheit(c) β€” formula: (c * 9/5) + 32
  2. A function expression capitalize that capitalizes the first letter of a string
  3. An IIFE that initializes an app counter starting at 100 and logs it

Verify that calling celsiusToFahrenheit before its declaration works (hoisting demo).

πŸ”₯ Challenge Exercise

Build a memoize(fn) function that wraps any function and caches its results. When called with the same arguments again, return the cached result without re-executing fn. Test it with the recursive factorial to demonstrate the speedup for repeated calls.

πŸ“‹ Summary

  • Function declarations are hoisted β€” callable before their definition in source code.
  • Function expressions (and arrow functions) are NOT hoisted β€” must be defined first.
  • IIFEs run immediately, creating private scope without polluting globals.
  • Functions are first-class values β€” assignable, passable, returnable.
  • Default parameters (ES6) eliminate the need for manual || default patterns.
  • Rest parameters collect extra arguments into an array.

Interview Questions

  • What is the difference between a function declaration and a function expression?
  • What is function hoisting and how does it differ for declarations vs expressions?
  • What is an IIFE and why would you use one?
  • What does it mean for functions to be "first-class citizens" in JavaScript?
  • What is the difference between a function and a method?

Frequently Asked Questions

Can a function have no return statement?+

Yes. If a function has no return statement (or a bare return;), it implicitly returns undefined. This is fine for functions whose purpose is side effects (logging, modifying DOM, etc.).

How many parameters can a JavaScript function have?+

There is no hard limit (it's engine-dependent, typically thousands), but more than 3–4 parameters is a code smell. Use an options object instead: function create({ name, age, role }).

What is the difference between a parameter and an argument?+

Parameters are the variable names listed in the function definition: function greet(name). Arguments are the actual values passed when calling the function: greet("Alice"). "Alice" is the argument; name is the parameter.