JavaScript Functions
Master JavaScript functions: learn function declaration, arrow functions, parameters, return values, scope, and closures. Write reusable, modular code with confidence.
What You'll Learn
What Are Functions?
A function is a reusable block of code designed to perform a specific task. Functions help you organize code, avoid repetition, and make programs easier to understand and maintain. You define a function once and call it many times.
Function Declaration
The most common way to create a function is using a function declaration. This syntax is hoisted, meaning you can call the function before declaring it.
Syntax
function functionName(parameter1, parameter2) {
// function body
// code to execute
return result; // optional return statement
}
Example
// Function declaration
function greet(name) {
return "Hello, " + name + "!";
}
// Calling the function
// greet("Alice") returns "Hello, Alice!"
// greet("Bob") returns "Hello, Bob!"
// Hoisting example - this works!
// sayHi(); // "Hi!" (called before declaration)
function sayHi() {
// Function body
}
Function Expression
A function expression defines a function as part of a larger expression. Unlike declarations, function expressions are NOT hoisted and must be defined before calling.
Syntax
// Named function expression
const add = function add(a, b) {
return a + b;
};
// Anonymous function expression (most common)
const subtract = function(a, b) {
return a - b;
};
// Immediately Invoked Function Expression (IIFE)
(function() {
// Code runs immediately
})();
Examples
// Function expression stored in variable
const multiply = function(a, b) {
return a * b;
};
// Call it like a regular function
// multiply(5, 3) returns 15
// Anonymous function as event handler
document.getElementById("btn").addEventListener("click", function() {
// Code runs when button is clicked
});
// Functions can be passed around
let calculate = multiply;
// calculate(4, 5) also returns 20
Arrow Functions
Arrow functions provide a concise syntax for writing functions. They are function expressions with implicit returns for single expressions.
Syntax
// Basic syntax
const functionName = (parameter) => {
// function body
return result;
};
// Single parameter (parentheses optional)
const square = x => x * x;
// Multiple parameters (parentheses required)
const add = (a, b) => a + b;
// No parameters
const greet = () => "Hello!";
// Multiple lines (need curly braces and return)
const divide = (a, b) => {
if (b === 0) return "Cannot divide by zero";
return a / b;
};
Examples
// Implicit return (one-liner)
const double = x => x * 2;
// double(5) returns 10
// Explicit return (multiple lines)
const greetUser = (firstName, lastName) => {
const fullName = firstName + " " + lastName;
return "Welcome, " + fullName;
};
// greetUser("John", "Doe") returns "Welcome, John Doe"
// Arrow functions in array methods
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(n => n * 2);
// doubled is [2, 4, 6, 8]
// Arrow functions in filtering
const evens = numbers.filter(n => n % 2 === 0);
// evens is [2, 4]
this binding. They inherit this from the surrounding scope, which is useful in callbacks and object methods.Parameters and Arguments
Parameters are variable names in the function definition. Arguments are the actual values passed when calling the function.
| Concept | Description | Example |
|---|---|---|
Parameter |
Variable in function definition | function add(a, b) — a and b are parameters |
Argument |
Value passed when calling function | add(5, 3) — 5 and 3 are arguments |
Default Parameter |
Value if no argument provided | function greet(name = "Guest") |
Rest Parameter |
Capture remaining arguments | function sum(...numbers) |
Default Parameters
// Default parameters
function greet(name = "Guest", greeting = "Hello") {
return greeting + ", " + name;
}
// greet() returns "Hello, Guest"
// greet("Alice") returns "Hello, Alice"
// greet("Bob", "Hi") returns "Hi, Bob"
// Arrow function with defaults
const multiply = (a = 1, b = 1) => a * b;
// multiply() returns 1
// multiply(5) returns 5
// multiply(3, 4) returns 12
Rest Parameters
// Rest parameters (...) collect remaining arguments
function sum(...numbers) {
let total = 0;
for (let num of numbers) {
total += num;
}
return total;
}
// sum(1, 2, 3) returns 6
// sum(1, 2, 3, 4, 5) returns 15
// sum() returns 0 (empty array)
// Combine regular and rest parameters
function printInfo(greeting, ...names) {
// greeting = "Hello"
// names = ["Alice", "Bob", "Charlie"]
}
Scope and Closures
Scope determines where variables are accessible. A closure is a function that has access to variables from its outer scope.
Function Scope
// Global scope
let globalVar = "I'm global";
function outer() {
// Function scope
let localVar = "I'm local";
function inner() {
// Inner function can access localVar
// inner scope
let innerVar = "I'm in inner";
}
// inner() is not accessible here (out of scope)
}
// globalVar is accessible everywhere
// localVar is only accessible inside outer()
// innerVar is only accessible inside inner()
Closures
// Closure example - function remembers outer variables
function makeCounter() {
let count = 0; // This variable is "closed over"
return function() {
count++;
return count;
};
}
const counter = makeCounter();
// counter() returns 1
// counter() returns 2
// counter() returns 3
// Each closure has its own count variable
const counter2 = makeCounter();
// counter2() returns 1 (separate count)
// Factory function using closure
function createMultiplier(factor) {
return function(number) {
return number * factor;
};
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
// double(5) returns 10
// triple(5) returns 15
Callbacks and Higher-Order Functions
A callback is a function passed as an argument to another function. A higher-order function is a function that takes or returns functions.
Callback Example
// Higher-order function that takes a callback
function processArray(array, callback) {
for (let i = 0; i < array.length; i++) {
array[i] = callback(array[i]);
}
return array;
}
// Using the higher-order function with different callbacks
const nums = [1, 2, 3];
// Callback 1: double numbers
const doubled = processArray([...nums], x => x * 2);
// doubled is [2, 4, 6]
// Callback 2: square numbers
const squared = processArray([...nums], x => x * x);
// squared is [1, 4, 9]
// Real-world examples
// setTimeout - delayed callback
setTimeout(() => {
// This code runs after 2 seconds
}, 2000);
// Array methods use callbacks
const even = nums.filter(n => n % 2 === 0);
Common Array Methods with Callbacks
const numbers = [1, 2, 3, 4, 5];
// map() - transform each element
const doubled = numbers.map(n => n * 2);
// [2, 4, 6, 8, 10]
// filter() - keep elements that match condition
const evens = numbers.filter(n => n % 2 === 0);
// [2, 4]
// forEach() - execute code for each element
numbers.forEach(n => {
// Execute for each element
});
// reduce() - combine to single value
const sum = numbers.reduce((total, n) => total + n, 0);
// 15
// find() - return first matching element
const firstEven = numbers.find(n => n % 2 === 0);
// 2
// some() - check if any element matches
const hasEven = numbers.some(n => n % 2 === 0);
// true
// every() - check if all elements match
const allPositive = numbers.every(n => n > 0);
// true
Best Practices
this, making them ideal for callbacks.
Key Takeaways
Functions are reusable blocks of code that perform tasks
Arrow functions provide concise syntax with implicit returns
Default and rest parameters make functions flexible
Closures create private variables and encapsulation
Callbacks enable higher-order functions and event handling
Hoist declarations but not expressions; declare before use
Frequently Asked Questions
A function is a reusable block of code that performs a specific task. Functions can accept parameters (inputs), perform operations, and return values (outputs). They help organize code, reduce repetition, and make programs modular and maintainable.
Function declarations are hoisted, meaning they're available before the line where they're defined. Function expressions are not hoisted and must be defined before being called. Function expressions can be anonymous and are often assigned to variables. Both work the same way once defined.
Arrow functions are a concise syntax for writing functions using the => operator. They support implicit returns for single expressions (no braces needed) and are particularly useful in callbacks and array methods. Arrow functions don't have their own this binding, which can be helpful in certain contexts.
Function scope means variables declared inside a function are only accessible within that function. This prevents global namespace pollution and variable conflicts. Each function creates its own scope, and inner functions can access variables from their parent functions (lexical scoping).
A closure is a function that has access to variables from its outer scope, even after the outer function returns. Closures are created every time a function is created and are powerful for creating private variables, data encapsulation, and factory functions. They're a fundamental concept in JavaScript.
A callback is a function passed as an argument to another function, to be executed later. Callbacks are commonly used with array methods (map, filter, forEach), event listeners, and asynchronous operations. Higher-order functions are functions that take or return other functions, often using callbacks.