Functions are the building blocks of any JavaScript program. They allow you to wrap a piece of code into a reusable block, give it a name, and execute it whenever you need it. Functions help organize code, reduce repetition, and make programs easier to understand and maintain.
A function is a set of instructions that performs a specific task. Think of it like a recipe — you write it once, and you can use it many times.
function greet() {
console.log("Hello, World! 👋");
}
// Calling (invoking) the function
greet(); // "Hello, World! 👋"
greet(); // "Hello, World! 👋"The most common way to define a function. Function declarations are hoisted (can be called before they're defined in the code).
function sayHello() {
console.log("Hello!");
}
sayHello(); // "Hello!"Assigning a function to a variable. These are not hoisted.
const sayGoodbye = function() {
console.log("Goodbye!");
};
sayGoodbye(); // "Goodbye!"Functions stored in variables are called anonymous functions when they don't have a name after the function keyword.
A shorter, modern syntax for writing functions.
const add = (a, b) => {
return a + b;
};
console.log(add(3, 5)); // 8// If the body is a single expression, you can omit {} and return
const multiply = (a, b) => a * b;
console.log(multiply(4, 5)); // 20
// Single parameter: parentheses are optional
const square = x => x * x;
console.log(square(5)); // 25
// No parameters: parentheses are required
const getRandom = () => Math.random();// Function Declaration
function add1(a, b) {
return a + b;
}
// Function Expression
const add2 = function(a, b) {
return a + b;
};
// Arrow Function
const add3 = (a, b) => a + b;All three produce the same result. Choose based on context and team conventions.
- Parameters are the variables listed in the function definition
- Arguments are the actual values passed when calling the function
function greet(name) { // 'name' is a parameter
console.log("Hello, " + name);
}
greet("Alice"); // "Alice" is an argument
greet("Bob"); // "Bob" is an argumentfunction introduce(firstName, lastName, age) {
console.log(`Hi, I'm ${firstName} ${lastName} and I'm ${age} years old.`);
}
introduce("Alice", "Smith", 25);
// "Hi, I'm Alice Smith and I'm 25 years old."function greet(name = "Guest") {
console.log(`Hello, ${name}!`);
}
greet("Alice"); // "Hello, Alice!"
greet(); // "Hello, Guest!"Capture any number of arguments into an array:
function sum(...numbers) {
let total = 0;
for (let num of numbers) {
total += num;
}
return total;
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(10, 20)); // 30
console.log(sum()); // 0In non-arrow functions, arguments is an array-like object containing all passed arguments:
function showArgs() {
console.log(arguments);
console.log(arguments[0]);
console.log(arguments.length);
}
showArgs("a", "b", "c");
// ["a", "b", "c"]
// "a"
// 3Note:
argumentsdoesn't exist in arrow functions. Prefer rest parameters (...args) in modern code.
Functions can send data back using the return statement. Once return executes, the function stops immediately.
function add(a, b) {
return a + b;
}
let result = add(10, 20);
console.log(result); // 30If a function doesn't explicitly return anything, it returns undefined:
function logMessage(msg) {
console.log(msg);
}
let output = logMessage("Hello");
console.log(output); // undefinedUse return to exit a function early:
function divide(a, b) {
if (b === 0) {
return "Cannot divide by zero!";
}
return a / b;
}
console.log(divide(10, 2)); // 5
console.log(divide(10, 0)); // "Cannot divide by zero!"Scope determines where variables are accessible in your code.
Variables declared with var inside a function are only accessible within that function:
function example() {
var message = "I'm inside the function";
console.log(message); // Works
}
example();
// console.log(message); // ❌ Error! Not accessible outsideVariables declared with let and const are scoped to the nearest {} block:
function demo() {
if (true) {
let blockVar = "I'm block-scoped";
const alsoBlock = "Me too";
var functionVar = "I'm function-scoped";
}
// console.log(blockVar); // ❌ Error!
// console.log(alsoBlock); // ❌ Error!
console.log(functionVar); // ✅ Works!
}Variables declared outside any function or block are globally accessible:
let globalVar = "I'm global";
function showGlobal() {
console.log(globalVar); // ✅ Accessible
}
showGlobal();
console.log(globalVar); // ✅ AccessibleBest Practice: Avoid global variables. They can be accidentally modified from anywhere, leading to bugs.
Functions that operate on other functions — either by taking them as arguments or returning them.
function executeOperation(a, b, operation) {
return operation(a, b);
}
function add(x, y) {
return x + y;
}
function multiply(x, y) {
return x * y;
}
console.log(executeOperation(5, 3, add)); // 8
console.log(executeOperation(5, 3, multiply)); // 15
// With arrow function (inline)
console.log(executeOperation(5, 3, (x, y) => x - y)); // 2function makeMultiplier(factor) {
return function(number) {
return number * factor;
};
}
const double = makeMultiplier(2);
const triple = makeMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15Functions that run immediately after being defined. Useful for creating private scope.
(function() {
let privateVar = "I'm private";
console.log(privateVar);
})();
// console.log(privateVar); // ❌ Error! Not accessible
// Arrow function IIFE
(() => {
console.log("IIFE with arrow function");
})();A function that calls itself. Must have a base case to prevent infinite loops.
function factorial(n) {
// Base case
if (n <= 1) {
return 1;
}
// Recursive case
return n * factorial(n - 1);
}
console.log(factorial(5)); // 120 (5 × 4 × 3 × 2 × 1)factorial(5)
→ 5 * factorial(4)
→ 5 * (4 * factorial(3))
→ 5 * (4 * (3 * factorial(2)))
→ 5 * (4 * (3 * (2 * factorial(1))))
→ 5 * (4 * (3 * (2 * 1)))
→ 120function countdown(n) {
if (n <= 0) {
console.log("Blast off! 🚀");
return;
}
console.log(n);
countdown(n - 1);
}
countdown(5);
// 5, 4, 3, 2, 1, "Blast off! 🚀"A pure function:
- Always returns the same output for the same input
- Has no side effects (doesn't modify external state)
// ✅ Pure function
function add(a, b) {
return a + b;
}
// ❌ Impure function (side effect)
let total = 0;
function addToTotal(value) {
total += value; // Modifies external variable
}
// ❌ Impure function (different output for same input)
function getRandomNumber() {
return Math.random(); // Different every time!
}function isValidEmail(email) {
if (!email || email.length === 0) {
return false;
}
if (!email.includes("@")) {
return false;
}
return true;
}
console.log(isValidEmail("alice@example.com")); // true
console.log(isValidEmail("invalid")); // falsefunction processPayment(amount, cardNumber) {
if (amount <= 0) return "Invalid amount";
if (!cardNumber) return "Card required";
if (cardNumber.length !== 16) return "Invalid card";
return `Processing $${amount}...`;
}function createUser(config) {
const defaults = {
name: "Guest",
role: "user",
isActive: true
};
const user = { ...defaults, ...config };
return user;
}
console.log(createUser({ name: "Alice" }));
// { name: "Alice", role: "user", isActive: true }function double(x) {
x * 2; // ❌ No return!
}
console.log(double(5)); // undefined
// ✅ Fixed
function double(x) {
return x * 2;
}function greet() {
return "Hello!";
}
console.log(greet); // [Function: greet] — the function itself
console.log(greet()); // "Hello!" — the result of calling itfunction addToArray(arr, value) {
arr.push(value); // ❌ Mutates the original array!
return arr;
}
// ✅ Better: return a new array
function addToArraySafe(arr, value) {
return [...arr, value];
}// ❌ Hard to read and use
function createUser(name, email, age, city, country, zip, isAdmin, role) {
// ...
}
// ✅ Use an object
function createUser(options) {
const { name, email, age, city, country, zip, isAdmin, role } = options;
// ...
}Write functions to convert between Celsius and Fahrenheit:
function celsiusToFahrenheit(c) {
// F = (C × 9/5) + 32
}
function fahrenheitToCelsius(f) {
// C = (F - 32) × 5/9
}Write a function that checks if a number is prime.
function isPrime(n) {
// Return true if n is prime, false otherwise
}
console.log(isPrime(7)); // true
console.log(isPrime(10)); // false
console.log(isPrime(1)); // falseWrite a recursive function to find the nth Fibonacci number.
function fibonacci(n) {
// fib(0) = 0, fib(1) = 1
// fib(n) = fib(n-1) + fib(n-2)
}
console.log(fibonacci(6)); // 8 (0, 1, 1, 2, 3, 5, 8)function calculate(a, b, operation) {
// operation is a callback function
}
calculate(10, 5, (x, y) => x + y); // 15
calculate(10, 5, (x, y) => x * y); // 50function compose(f, g) {
// Return a new function that is f(g(x))
}
const add1 = x => x + 1;
const double = x => x * 2;
const addThenDouble = compose(double, add1);
console.log(addThenDouble(5)); // 12 (5 + 1 = 6, then 6 * 2 = 12)- Function Declaration:
function name() {}— hoisted - Function Expression:
const name = function() {}— not hoisted - Arrow Function:
const name = () => {}— concise, no ownthis - Parameters are in the definition; arguments are passed when calling
- Use
returnto send values back from a function - Scope controls where variables are accessible: global, function, block
- Higher-order functions take or return other functions
- Recursion is a function calling itself with a base case
- Pure functions have no side effects and consistent outputs
Now that you understand functions, explore:
- Arrays — storing and manipulating collections
- Objects — grouping related data and functions
- Closures — advanced scope behavior
- Callbacks and Async — functions that run later
Happy coding! 🚀