Functions in JavaScript
What Is a Function?
A function is a block of code that can be executed repeatedly under a specific name. Functions help us to:
- Avoid repeating code (DRY — Don't Repeat Yourself)
- Break problems down into small pieces
- Make testing and debugging easier
- Make code more readable
1. Function Declaration
// Syntax: function function_name(parameter) { ... }
function greetStudent(name) {
console.log(`Welcome, ${name}!`);
}
// Calling the function
greetStudent("John Smith"); // "Welcome, John Smith!"
greetStudent("Mike Brown"); // "Welcome, Mike Brown!"
Function with a Return Value
// Function returning a value
function calcAverage(a, b, c) {
const average = (a + b + c) / 3;
return average;
}
const result = calcAverage(85, 90, 78);
console.log(`Average: ${result}`); // "Average: 84.33..."
// Returning an object
function createStudentProfile(studentId, name, gpa) {
return {
studentId: studentId,
name: name,
gpa: gpa,
classification: gpa >= 3.5 ? "Cum Laude" : "Non Cum Laude",
createdAt: new Date().toISOString()
};
}
const profile = createStudentProfile("2024100123", "John Smith", 3.75);
console.log(profile);
Hoisting
Function declarations are fully hoisted, which means they can be called before they are declared.
// ✅ Can be called before its declaration
console.log(calcCredits(20)); // "Total credits: 20"
function calcCredits(credits) {
return `Total credits: ${credits}`;
}
2. Function Expression
A function stored in a variable.
// Syntax: const function_name = function(parameter) { ... }
const add = function(a, b) {
return a + b;
};
console.log(add(10, 5)); // 15
// Not hoisted — must be declared first
// console.log(multiply(3, 4)); // ReferenceError!
const multiply = function(a, b) {
return a * b;
};
3. Arrow Function (ES6)
A more concise syntax for function expressions.
// Arrow function — one parameter, one statement
const square = x => x * x;
console.log(square(5)); // 25
// Arrow function — multiple parameters
const add = (a, b) => a + b;
console.log(add(10, 5)); // 15
// Arrow function — code block (needs an explicit return)
const determineGrade = (score) => {
if (score >= 90) return "A";
if (score >= 80) return "B";
if (score >= 70) return "C";
if (score >= 60) return "D";
return "E";
};
console.log(determineGrade(85)); // "B"
// Arrow function — returning an object literal
const createStudent = (studentId, name) => ({
studentId: studentId,
name: name,
createdAt: new Date()
});
const stu = createStudent("2024100123", "John");
console.log(stu); // { studentId: "2024100123", name: "John", createdAt: ... }
4. Parameters vs Arguments
// Parameters: the variable names in the function declaration
// Arguments: the actual values when the function is called
function sumTotal(score1, score2, score3) { // <- these are parameters
return score1 + score2 + score3;
}
// 85, 90, 78 are arguments
const total = sumTotal(85, 90, 78);
console.log(total); // 253
// arguments object (only available in function expressions & declarations)
function sumAll() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
console.log(sumAll(85, 90, 78, 88, 92)); // 433
5. Default Parameters (ES6)
Provides a default value when a parameter is not passed.
// Default parameters
function createAccount(name, role = "student", status = "active") {
return {
name: name,
role: role,
status: status,
createdAt: new Date()
};
}
console.log(createAccount("John"));
// { name: "John", role: "student", status: "active" }
console.log(createAccount("Mike", "instructor"));
// { name: "Mike", role: "instructor", status: "active" }
console.log(createAccount("Anna", "admin", "inactive"));
// { name: "Anna", role: "admin", status: "inactive" }
// Default parameter with an expression
function createStudentId(name, year = new Date().getFullYear().toString().slice(-2)) {
const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
return `${year}${random}`;
}
console.log(createStudentId("John")); // "241234" (year + random)
6. Rest Parameters (ES6)
Collects all arguments into an array.
// Rest parameters
function calcAverage(...scores) {
const total = scores.reduce((sum, n) => sum + n, 0);
return total / scores.length;
}
console.log(calcAverage(85, 90, 78, 92, 88)); // 86.6
console.log(calcAverage(80, 85)); // 82.5
// Rest parameters alongside regular parameters
function createAnnouncement(title, ...students) {
console.log(`\n=== ${title} ===`);
students.forEach((m, i) => {
console.log(`${i + 1}. ${m}`);
});
}
createAnnouncement("Top Graduates", "John Smith", "Mike Brown", "Anna Green");
// === Top Graduates ===
// 1. John Smith
// 2. Mike Brown
// 3. Anna Green
7. Callback Functions
A function passed as an argumentt to another function.
// Basic callback
function processData(data, callback) {
const result = data.map(item => item.toUpperCase());
callback(result);
}
processData(["john", "mike", "anna"], (result) => {
console.log(result); // ["JOHN", "MIKE", "ANNA"]
});
// Callback in an academic portal
function fetchStudentData(studentId, onSuccess, onError) {
// Simulated data retrieval
const database = {
"2024100123": { name: "John Smith", gpa: 3.75 },
"2024100124": { name: "Mike Brown", gpa: 3.50 }
};
const data = database[studentId];
if (data) {
onSuccess(data);
} else {
onError(`No data found for student ID ${studentId}`);
}
}
// Usage with callbacks
fetchStudentData(
"2024100123",
(data) => console.log(`Name: ${data.name}, GPA: ${data.gpa}`),
(error) => console.error(error)
);
fetchStudentData(
"2024100999",
(data) => console.log(`Name: ${data.name}`),
(error) => console.error(error) // "No data found for student ID 2024100999"
);
8. Immediately Invoked Function Expression (IIFE)
A function that runs immediately when it is declared.
// IIFE
(function() {
console.log("This is an IIFE — it runs immediately!");
})();
// IIFE with parameters
(function(name) {
console.log(`Hello, ${name}! This is an IIFE.`);
})("John");
// Arrow function IIFE
(() => {
console.log("Arrow IIFE!");
})();
// Usage: creating a private scope
const AcademicSystem = (function() {
// Private variables
const MAX_CREDITS = 24;
const MIN_GPA = 2.0;
// Private function
function validateCredits(credits) {
return credits >= 1 && credits <= MAX_CREDITS;
}
// Public function
return {
enrollInCourse: function(student, course) {
if (validateCredits(course.credits + student.creditsTaken)) {
student.courses.push(course);
student.creditsTaken += course.credits;
return { success: true, message: "Successfully enrolled in the course" };
}
return { success: false, message: `Exceeds the maximum of ${MAX_CREDITS} credits` };
}
};
})();
// Usage
const john = { name: "John", creditsTaken: 18, courses: [] };
const result = AcademicSystem.enrollInCourse(john, { code: "IF104", name: "Artificial Intelligence", credits: 3 });
console.log(result); // { success: true, message: "Successfully enrolled in the course" }
9. Pure Functions
A function that always produces the same output for the same input, with no side effects.
// ✅ Pure function
function calcGPA(scoreArray) {
const total = scoreArray.reduce((sum, n) => sum + n, 0);
return total / scoreArray.length;
}
console.log(calcGPA([85, 90, 78])); // always 84.33...
// ❌ Impure function (has side effects)
let callCount = 0;
function calcGPAImpure(scoreArray) {
callCount++; // modifies external state
const total = scoreArray.reduce((sum, n) => sum + n, 0);
return total / scoreArray.length;
}
Case Study: Functions for Calculating Student Average Scores
// === STUDENT GRADING SYSTEM ===
// Pure function: calculate the average
function calcAverage(...scores) {
if (scores.length === 0) return 0;
const total = scores.reduce((sum, n) => sum + n, 0);
return Math.round((total / scores.length) * 100) / 100;
}
// Function: determine the grade
function determineGrade(score) {
if (score >= 90) return { grade: "A", rating: "Excellent" };
if (score >= 80) return { grade: "B", rating: "Good" };
if (score >= 70) return { grade: "C", rating: "Fair" };
if (score >= 60) return { grade: "D", rating: "Poor" };
return { grade: "E", rating: "Very Poor" };
}
// Function: create a grade report card
function createGradeCard(studentId, name, scoreList) {
const average = calcAverage(...scoreList);
const grade = determineGrade(average);
return {
studentId: studentId,
name: name,
scores: scoreList,
average: average,
grade: grade.grade,
rating: grade.rating,
passed: average >= 60,
academicYear: "2024/2025"
};
}
// Function: display the grade report card
function showGradeCard(card) {
console.log("\n╔════════════════════════════════════╗");
console.log("║ STUDENT GRADE REPORT CARD ║");
console.log("╠════════════════════════════════════╣");
console.log(`║ ID : ${card.studentId.padEnd(24)}║`);
console.log(`║ Name : ${card.name.padEnd(24)}║`);
console.log("╠════════════════════════════════════╣");
console.log("║ SCORES: ║");
card.scores.forEach((n, i) => {
console.log(`║ Week ${i + 1}: ${String(n).padStart(3)} ║`);
});
console.log("╠════════════════════════════════════╣");
console.log(`║ Average : ${String(card.average).padEnd(22)}║`);
console.log(`║ Grade : ${card.grade.padEnd(22)}║`);
console.log(`║ Rating : ${card.rating.padEnd(22)}║`);
console.log(`║ Status : ${(card.passed ? "PASS" : "FAIL").padEnd(22)}║`);
console.log("╚════════════════════════════════════╝");
}
// === USAGE ===
const studentList = [
{ studentId: "2024100123", name: "John Smith", scores: [85, 90, 78, 88, 92] },
{ studentId: "2024100124", name: "Mike Brown", scores: [70, 75, 68, 72, 80] },
{ studentId: "2024100125", name: "Anna Green", scores: [55, 60, 50, 58, 62] }
];
// Process all students
for (const s of studentList) {
const card = createGradeCard(s.studentId, s.name, s.scores);
showGradeCard(card);
}
// Class summary
console.log("\n=== CLASS SUMMARY ===");
const classAverage = calcAverage(
...studentList.map(m => calcAverage(...m.scores))
);
console.log(`Class average: ${classAverage}`);
Summary
| Type | Syntax | Hoisting | Use When |
|---|---|---|---|
| Declaration | function name() {} |
Yes | Main functions, utilities |
| Expression | const name = function() {} |
No | Callbacks, conditional branches |
| Arrow | const name = () => {} |
No | Short callbacks, pure functions |
| IIFE | (function() {})() |
No | Private scope, initialization |
| Default | function(a = 1) {} |
- | Optional parameters |
| Rest | function(...args) {} |
- | Variable arguments |
Use arrow functions for short callbacks, function declarations for main functions, and default/rest parameters for flexibility.