JavaScript Functions — Complete Guide
Phase 2 — Control Flow & Functions
Module 7 — Functions
Functions are one of the most important concepts in JavaScript. Every modern JavaScript application—whether it's a website, React application, Node.js API, or enterprise system—is built around functions.
Functions allow you to organize code into reusable, maintainable, and modular blocks.
In professional development, functions are used for:
- Processing user input
- Making API requests
- DOM manipulation
- Event handling
- Database operations
- Authentication
- Business logic
- Utility libraries
By the end of this module, you'll understand how to create, use, and compose functions effectively.
What is a Function?
A function is a reusable block of code that performs a specific task.
Instead of writing the same logic multiple times, you write it once and call it whenever needed.
Example:
1function greet() { 2 console.log("Hello JavaScript"); 3} 4 5greet();
Output
1Hello JavaScript
Function Anatomy
1function greet(name) { 2 3 return `Hello ${name}`; 4 5} 6 7greet("Ankit"); 8 9│ 10├── function keyword 11├── function name 12├── parameter 13├── function body 14├── return value 15└── function call
Function Declaration
A function declaration is the standard way to define a function.
Syntax
1function functionName(parameters) { 2 3}
Example
1function add(a, b) { 2 return a + b; 3} 4 5console.log(add(10, 20));
Output
130
Function Parameters
1function introduce(name, age) { 2 3 console.log(name); 4 console.log(age); 5 6} 7 8introduce("Ankit", 23);
Output
1Ankit 223
Default Parameters
1function greet(name = "Guest") { 2 3 console.log(`Hello ${name}`); 4 5} 6 7greet(); 8greet("Ankit");
Output
1Hello Guest 2Hello Ankit
Return Statement
1function square(number) { 2 3 return number * number; 4 5} 6 7const result = square(8); 8 9console.log(result);
Output
164
Function Expression
Functions can be assigned to variables.
1const multiply = function(a, b) { 2 3 return a * b; 4 5}; 6 7console.log(multiply(4, 5));
Output
120
Unlike function declarations, function expressions are not fully hoisted.
Arrow Function
Arrow functions were introduced in ES6.
Syntax
1const add = (a, b) => { 2 3 return a + b; 4 5};
Short Version
1const add = (a, b) => a + b; 2 3console.log(add(5, 6));
Output
111
Arrow Function vs Regular Function
| Feature | Regular Function | Arrow Function |
|---|---|---|
Own this | ✅ | ❌ |
| Constructor | ✅ | ❌ |
| Short syntax | ❌ | ✅ |
| Best for methods | ✅ | ⚠️ |
| Best for callbacks | ⚠️ | ✅ |
Anonymous Function
An anonymous function has no name.
1const message = function() { 2 3 console.log("Hello"); 4 5}; 6 7message();
Output
1Hello
Commonly used in callbacks and event listeners.
Callback Function
A callback is a function passed as an argument to another function.
1function process(callback) { 2 3 callback(); 4 5} 6 7process(function() { 8 console.log("Processing..."); 9});
Output
1Processing...
Arrow Callback
1setTimeout(() => { 2 3 console.log("Executed"); 4 5}, 1000);
Callbacks are widely used in:
- Event listeners
- AJAX
- Timers
- Array methods
- Node.js APIs
Recursive Function
A recursive function calls itself until a stopping condition is reached.
Example
1function countdown(number) { 2 3 if (number === 0) 4 return; 5 6 console.log(number); 7 8 countdown(number - 1); 9 10} 11 12countdown(5);
Output
15 24 33 42 51
Factorial Example
1function factorial(n) { 2 3 if (n === 1) 4 return 1; 5 6 return n * factorial(n - 1); 7 8} 9 10console.log(factorial(5));
Output
1120
Higher Order Function
A higher-order function:
- Accepts another function as an argument
- Returns a function
Example
1function calculate(a, b, operation) { 2 3 return operation(a, b); 4 5} 6 7const result = calculate(10, 20, (x, y) => x + y); 8 9console.log(result);
Output
130
Examples of higher-order functions:
- map()
- filter()
- reduce()
- sort()
- forEach()
Pure Function
A pure function:
- Always returns the same output for the same input.
- Has no side effects.
Example
1function add(a, b) { 2 3 return a + b; 4 5}
Impure Function
1let count = 0; 2 3function increment() { 4 5 count++; 6 7}
Pure functions are easier to test and maintain.
Closure
A closure allows an inner function to access variables from its outer function even after the outer function has finished executing.
Example
1function counter() { 2 3 let count = 0; 4 5 return function() { 6 7 count++; 8 9 return count; 10 11 }; 12 13} 14 15const increment = counter(); 16 17console.log(increment()); 18console.log(increment()); 19console.log(increment());
Output
11 22 33
Closures are commonly used for:
- Private variables
- Data encapsulation
- Memoization
- Event handlers
IIFE (Immediately Invoked Function Expression)
An IIFE runs immediately after it is defined.
1(function() { 2 3 console.log("Application Started"); 4 5})();
Output
1Application Started
Arrow Version
1(() => { 2 3 console.log("Running"); 4 5})();
Uses:
- Private scope
- Initialization code
- Avoiding global variables
Generator Function
Generators pause and resume execution using yield.
Syntax
1function* numbers() { 2 3 yield 1; 4 yield 2; 5 yield 3; 6 7} 8 9const generator = numbers(); 10 11console.log(generator.next()); 12console.log(generator.next()); 13console.log(generator.next());
Output
1{ value: 1, done: false } 2{ value: 2, done: false } 3{ value: 3, done: false }
Generators are useful for:
- Lazy evaluation
- Infinite sequences
- Custom iterators
- Streaming large datasets
Async Function
Async functions simplify asynchronous programming.
1async function getUser() { 2 3 return { 4 name: "Ankit" 5 }; 6 7} 8 9getUser().then(console.log);
Output
1{ 2 name: "Ankit" 3}
Using await
1async function fetchData() { 2 3 const response = await fetch( 4 "https://jsonplaceholder.typicode.com/users/1" 5 ); 6 7 const data = await response.json(); 8 9 console.log(data); 10 11} 12 13fetchData();
Benefits:
- Cleaner syntax
- Easier error handling
- Better readability
- Replaces callback chains
Function Hoisting
Function declarations are hoisted.
1greet(); 2 3function greet() { 4 5 console.log("Hello"); 6 7}
Output
1Hello
Function expressions are not.
1sayHello(); 2 3const sayHello = function() { 4 5 console.log("Hello"); 6 7};
Output
1ReferenceError
Real-World Example
1const users = [ 2 { name: "Ankit", age: 23 }, 3 { name: "Rahul", age: 18 }, 4 { name: "Priya", age: 28 } 5]; 6 7const adults = users.filter( 8 user => user.age >= 18 9); 10 11const names = adults.map( 12 user => user.name 13); 14 15console.log(names);
Output
1["Ankit", "Rahul", "Priya"]
Best Practices
- Use descriptive function names.
- Keep functions focused on a single responsibility.
- Prefer
constwith arrow functions for callbacks and utilities. - Use regular functions for object methods that rely on
this. - Write pure functions whenever possible.
- Avoid deeply nested callbacks; use
async/awaitinstead. - Return values instead of modifying global variables.
- Use closures to encapsulate private state.
Mini Project — Student Management System
index.html
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Student Management</title> 6</head> 7<body> 8 9<h2>Student Management System</h2> 10 11<div id="output"></div> 12 13<script src="script.js"></script> 14 15</body> 16</html>
script.js
1const students = [ 2 { name: "Ankit", marks: 92 }, 3 { name: "Rahul", marks: 74 }, 4 { name: "Priya", marks: 86 } 5]; 6 7const getGrade = (marks) => { 8 9 if (marks >= 90) return "A"; 10 if (marks >= 75) return "B"; 11 if (marks >= 60) return "C"; 12 13 return "D"; 14 15}; 16 17const output = document.getElementById("output"); 18 19students.forEach(student => { 20 21 output.innerHTML += ` 22 <p> 23 ${student.name} 24 - 25 ${student.marks} 26 - 27 Grade ${getGrade(student.marks)} 28 </p> 29 `; 30 31});
Function Comparison
| Function Type | Use Case | ES Version |
|---|---|---|
| Function Declaration | General reusable functions | ES1 |
| Function Expression | Store functions in variables | ES3 |
| Arrow Function | Callbacks, utilities | ES6 |
| Anonymous Function | Event handlers, callbacks | ES3 |
| Callback Function | Async programming | ES3 |
| Recursive Function | Tree traversal, factorial | ES1 |
| Higher-Order Function | Functional programming | ES3 |
| Pure Function | Predictable business logic | ES1 |
| Closure | Private state, encapsulation | ES3 |
| IIFE | Initialization, private scope | ES3 |
| Generator Function | Lazy iteration | ES6 |
| Async Function | Asynchronous programming | ES2017 |
Summary
In this module, you learned:
- How to declare and invoke functions.
- The difference between function declarations, expressions, and arrow functions.
- How anonymous functions and callbacks power event-driven programming.
- How recursion solves problems by calling a function from within itself.
- How higher-order functions enable functional programming patterns.
- Why pure functions improve maintainability and testing.
- How closures preserve access to outer variables for encapsulation.
- How IIFEs create isolated scopes and execute immediately.
- How generator functions provide lazy, resumable execution.
- How
asyncfunctions andawaitsimplify asynchronous programming.
These concepts form the foundation of modern JavaScript development and are used extensively in frameworks like React, Next.js, Vue, Angular, Node.js, and modern backend APIs.