9. Functions
Function Declaration
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet("John")); // "Hello, John!"
Function Expression
const greet = function(name) {
return `Hello, ${name}!`;
};
console.log(greet("Jane")); // "Hello, Jane!"
Arrow Functions (ES6+)
// Basic arrow function
const greet = (name) => `Hello, ${name}!`;
// Multiple parameters
const add = (a, b) => a + b;
// No parameters
const sayHello = () => "Hello!";
// Multiple statements (need curly braces and return)
const calculate = (a, b) => {
let result = a + b;
return result * 2;
};
// Returning objects
const createPerson = (name, age) => ({ name, age });
Parameters
Default Parameters (ES6+)
function greet(name = "Guest", greeting = "Hello") {
return `${greeting}, ${name}!`;
}
console.log(greet()); // "Hello, Guest!"
console.log(greet("John")); // "Hello, John!"
console.log(greet("John", "Hi")); // "Hi, John!"
Rest Parameters (ES6+)
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15
Destructuring Parameters
function printUser({ name, age, city = "Unknown" }) {
console.log(`${name} is ${age} years old and lives in ${city}.`);
}
const user = { name: "John", age: 30 };
printUser(user); // "John is 30 years old and lives in Unknown."
Function Scope and Closures
Function Scope
function outer() {
let outerVar = "I'm outer";
function inner() {
let innerVar = "I'm inner";
console.log(outerVar); // Can access outer scope
console.log(innerVar); // Can access own scope
}
inner();
// console.log(innerVar); // Error: innerVar not accessible
}
outer();
Closures
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
Higher-Order Functions
Functions that take other functions as parameters or return functions:
function applyOperation(a, b, operation) {
return operation(a, b);
}
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;
console.log(applyOperation(5, 3, add)); // 8
console.log(applyOperation(5, 3, multiply)); // 15
Immediately Invoked Function Expressions (IIFE)
// Traditional IIFE
(function() {
console.log("This runs immediately!");
})();
// Arrow function IIFE
(() => {
console.log("Arrow IIFE!");
})();
Function Methods
call(), apply(), bind()
function greet(greeting, punctuation) {
return `${greeting}, ${this.name}${punctuation}`;
}
const person = { name: "John" };
// call() - passes arguments individually
console.log(greet.call(person, "Hello", "!")); // "Hello, John!"
// apply() - passes arguments as array
console.log(greet.apply(person, ["Hi", "."])); // "Hi, John."
// bind() - creates new function with bound context
const boundGreet = greet.bind(person, "Hey", "!");
console.log(boundGreet()); // "Hey, John!"
Recursive Functions
function factorial(n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
console.log(factorial(5)); // 120
// Tail recursion (optimized in some engines)
function factorialTail(n, accumulator = 1) {
if (n <= 1) {
return accumulator;
}
return factorialTail(n - 1, n * accumulator);
}
Generator Functions (ES6+)
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
const generator = numberGenerator();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: undefined, done: true }
Async Functions (ES8+)
async function fetchUserData(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
const userData = await response.json();
return userData;
} catch (error) {
console.error("Error fetching user data:", error);
}
}
// Usage
fetchUserData(123).then(user => console.log(user));
Function Properties
function myFunction(a, b, c) {
// Function body
}
console.log(myFunction.length); // 3 (number of parameters)
console.log(myFunction.name); // "myFunction"
Next Steps
Functions are fundamental to JavaScript programming. Next, let's explore objects and prototypes, the building blocks of object-oriented programming in ECMAScript.