Functions are reusable blocks of code that perform a specific task.
Instead of writing the same code repeatedly, we can place it inside a function and call it whenever needed.
A function is a block of code designed to perform a particular task.
Example:
function greet() {
console.log("Hello");
}
Calling the function:
greet();
Output:
Hello
Functions provide:
Without functions:
console.log("Welcome");
console.log("Welcome");
console.log("Welcome");
With functions:
function welcome() {
console.log("Welcome");
}
welcome();
welcome();
welcome();
The function is written once and can be reused whenever needed.
A Function Declaration is the most common way to create a function.
function functionName() {
// code
}
function greet() {
console.log("Hello World");
}
Calling:
greet();
Output:
Hello World
Functions can return a value using the return keyword.
Example:
function add() {
return 10 + 5;
}
Calling the function:
const result = add();
console.log(result);
Output:
15
The return keyword sends a value back to where the function was called.
A Function Expression is a function stored inside a variable.
const variableName = function() {
// code
};
const greet = function() {
console.log("Hello");
};
Calling:
greet();
Output:
Hello
function greet() {
console.log("Hello");
}
const greet = function() {
console.log("Hello");
};
Function declarations are hoisted.
This works:
greet();
function greet() {
console.log("Hello");
}
Output:
Hello
Function expressions declared with const cannot be called before initialization.
greet();
const greet = function() {
console.log("Hello");
};
Output:
ReferenceError
Parameters allow functions to receive data.
function greet(name) {
// code
}
Here:
name
↓
Parameter
function greet(name) {
console.log("Hello " + name);
}
Calling:
greet("Samir");
Output:
Hello Samir
A function can receive multiple parameters.
function add(a, b) {
return a + b;
}
Calling:
add(10, 20);
Output:
30
Here:
a, b
↓
Parameters
10, 20
↓
Arguments
Consider this function:
function greet(name) {
console.log(name);
}
Here:
name
↓
Parameter
When calling the function:
greet("Samir");
Here:
"Samir"
↓
Argument
The difference is:
| Term | Meaning |
|---|---|
| Parameter | Variable defined in the function |
| Argument | Actual value passed to the function |
Default parameters provide fallback values when an argument is not provided.
function greet(name = "Guest") {
// code
}
function greet(name = "Guest") {
console.log(`Hello ${name}`);
}
Calling without an argument:
greet();
Output:
Hello Guest
Calling with an argument:
greet("Samir");
Output:
Hello Samir
Multiple parameters can have default values.
function createUser(
name = "Guest",
age = 18
) {
console.log(name, age);
}
Calling:
createUser();
Output:
Guest 18
Calling:
createUser("Samir", 21);
Output:
Samir 21
Rest parameters collect multiple arguments into an array.
function test(...values) {
// code
}
The ... syntax is used to collect the remaining arguments.
function sum(...numbers) {
console.log(numbers);
}
Calling:
sum(1, 2, 3, 4);
Output:
[1, 2, 3, 4]
Here:
1, 2, 3, 4
↓
Rest Parameter
↓
[1, 2, 3, 4]
function add(...numbers) {
let total = 0;
for (const num of numbers) {
total += num;
}
return total;
}
Calling:
add(10, 20, 30);
Output:
60
The function can accept any number of arguments:
add(1, 2);
add(1, 2, 3);
add(1, 2, 3, 4, 5);
Only one rest parameter is allowed.
The rest parameter must also be the last parameter.
Correct:
function test(a, b, ...rest) {
// code
}
Incorrect:
function test(...rest, a) {
// code
}
Also incorrect:
function test(...a, ...b) {
// code
}
Arrow Functions were introduced in ES6.
They provide a shorter syntax for writing functions.
function greet() {
console.log("Hello");
}
const greet = () => {
console.log("Hello");
};
Both can perform the same task, but arrow functions use a shorter syntax.
const greet = (name) => {
console.log(`Hello ${name}`);
};
Calling:
greet("Samir");
Output:
Hello Samir
Traditional function:
function add(a, b) {
return a + b;
}
Arrow function:
const add = (a, b) => {
return a + b;
};
Short form:
const add = (a, b) => a + b;
Calling:
add(10, 20);
Output:
30
When an arrow function contains only one expression, we can omit {} and return.
const multiply = (a, b) => a * b;
This automatically returns the result.
When an arrow function has only one parameter, parentheses are optional.
Instead of:
const square = (x) => {
return x * x;
};
We can write:
const square = x => x * x;
Calling:
square(5);
Output:
25
For multiple parameters, parentheses are required:
const add = (a, b) => a + b;
thisArrow functions do not have their own this.
They inherit this from the surrounding scope.
Traditional function:
function test() {
console.log(this);
}
Arrow function:
const test = () => {
console.log(this);
};
Their behavior with this is different.
The
thiskeyword is covered in detail in a later lesson.
IIFE stands for:
Immediately Invoked Function Expression
An IIFE is a function that executes immediately after it is created.
(function() {
console.log("Hello");
})();
Output:
Hello
Notice:
Function Created
↓
Immediately Called
↓
Code Executes
An IIFE can also use an arrow function.
(() => {
console.log("Hello");
})();
Output:
Hello
An IIFE can create a private scope.
Example:
(function() {
const secret = "123";
console.log(secret);
})();
Output:
123
Outside:
console.log(secret);
Output:
ReferenceError
The variable exists only inside the function.
IIFE
│
└── secret
↓
Private Scope
IIFEs were especially common before modern JavaScript modules became widely used.
Recursion occurs when a function calls itself.
function countdown(n) {
console.log(n);
countdown(n - 1);
}
Problem:
Infinite Recursion
The function continues calling itself because there is no stopping condition.
Every recursive function needs a base case.
A base case tells the function when to stop.
Example:
function countdown(n) {
if (n === 0) {
return;
}
console.log(n);
countdown(n - 1);
}
Calling:
countdown(5);
Output:
5
4
3
2
1
Calling:
countdown(3);
Execution:
countdown(3)
↓
Print 3
↓
countdown(2)
↓
Print 2
↓
countdown(1)
↓
Print 1
↓
countdown(0)
↓
Stop
The base case prevents infinite recursion.
A common example of recursion is calculating a factorial.
Mathematical formula:
5! = 5 × 4 × 3 × 2 × 1
Result:
120
Recursive solution:
function factorial(n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
Calling:
factorial(5);
Output:
120
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
↓
120
Variables declared inside functions are local to that function.
Example:
function test() {
const message = "Hello";
console.log(message);
}
Calling:
test();
Output:
Hello
Trying to access the variable outside:
console.log(message);
Output:
ReferenceError
Visual:
Global Scope
│
└── test()
│
└── message = "Hello"
message can only be accessed inside test().
Functions can send values back using the return keyword.
Example:
function multiply(a, b) {
return a * b;
}
Calling:
const result = multiply(5, 4);
console.log(result);
Output:
20
Visual:
5, 4
↓
multiply()
↓
5 × 4
↓
return 20
↓
result = 20
return Stops Function ExecutionWhen JavaScript reaches return, the function stops executing.
Example:
function test() {
console.log("Before");
return;
console.log("After");
}
test();
Output:
Before
"After" is never printed because the function already returned.
returnA function without an explicit return returns undefined.
Example:
function greet() {
console.log("Hello");
}
const result = greet();
console.log(result);
Output:
Hello
undefined
const calculateTotal = (
price,
quantity = 1
) => {
return price * quantity;
};
console.log(
calculateTotal(100, 3)
);
Output:
300
Concepts used:
Arrow Function
↓
Parameters
↓
Default Parameter
↓
Calculation
↓
Return Value
| Type | Example |
|---|---|
| Function Declaration | function greet(){} |
| Function Expression | const greet = function(){} |
| Arrow Function | const greet = () => {} |
| IIFE | (function(){})() |
| Recursive Function | Function calling itself |
| Concept | Example | Purpose |
|---|---|---|
| Parameter | function greet(name) |
Receives data |
| Argument | greet("Samir") |
Sends actual value |
| Default Parameter | name = "Guest" |
Provides fallback |
| Rest Parameter | ...numbers |
Collects multiple arguments |
Good:
function calculateTotal() {
// code
}
Bad:
function x() {
// code
}
Function names should describe what the function does.
A function should ideally perform one clear task.
Good:
function calculateTotal(price, quantity) {
return price * quantity;
}
Avoid creating one huge function that performs many unrelated tasks.
Instead of:
function greetSamir() {
console.log("Hello Samir");
}
function greetRam() {
console.log("Hello Ram");
}
Use:
function greet(name) {
console.log(`Hello ${name}`);
}
greet("Samir");
greet("Ram");
Example:
const numbers = [1, 2, 3];
numbers.map(
number => number * 2
);
Arrow functions are especially common for short callbacks.
function greet(name = "Guest") {
console.log(`Hello ${name}`);
}
This prevents unnecessary checks for missing values.
function add(a, b) {
return a + b;
}
Then:
const result = add(10, 20);
Good:
function countdown(n) {
if (n === 0) {
return;
}
countdown(n - 1);
}
Without a base case, recursion can continue until JavaScript throws:
RangeError: Maximum call stack size exceeded
| Concept | Purpose |
|---|---|
| Function Declaration | Standard function |
| Function Expression | Function stored in a variable |
| Parameters | Input variables |
| Arguments | Values passed to a function |
| Default Parameters | Fallback values |
| Rest Parameters | Collect multiple arguments |
| Arrow Functions | Shorter function syntax |
| IIFE | Execute immediately |
| Recursion | Function calling itself |
| Base Case | Stops recursion |
| Return | Send a value back |
| Function Scope | Controls local variable access |
Functions are reusable blocks of code that make programs modular, organized, and maintainable.
Function Declaration
↓
Standard Function
Function Expression
↓
Function Stored in Variable
Parameters
↓
Receive Data
Arguments
↓
Provide Data
Return
↓
Send Result Back
Arrow Functions
↓
Shorter Modern Syntax
Rest Parameters
↓
Multiple Arguments
IIFE
↓
Immediate Execution
Recursion
↓
Function Calls Itself
The basic function workflow is:
Input
↓
Parameters
↓
Function
↓
Process Data
↓
Return
↓
Output
Example:
function add(a, b) {
return a + b;
}
const result = add(10, 20);
console.log(result);
Output:
30
Functions are one of the most important concepts in JavaScript because React components, event handlers, callbacks, API calls, hooks, and application logic are all built using functions.
Understanding functions properly makes it much easier to learn advanced JavaScript and React.