[Go to site: main page, start]

0% found this document useful (0 votes)
2 views101 pages

Source Code JavaScript 100 Coding Examples

The document contains a series of JavaScript exercises covering fundamental programming concepts such as variable declaration, arithmetic operations, string manipulation, conditional statements, loops, functions, arrays, and objects. Each exercise includes code examples and explanations to illustrate the concepts. The exercises are designed to help learners practice and understand basic to intermediate JavaScript programming skills.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views101 pages

Source Code JavaScript 100 Coding Examples

The document contains a series of JavaScript exercises covering fundamental programming concepts such as variable declaration, arithmetic operations, string manipulation, conditional statements, loops, functions, arrays, and objects. Each exercise includes code examples and explanations to illustrate the concepts. The exercises are designed to help learners practice and understand basic to intermediate JavaScript programming skills.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Exercise 1: Declare and Assign Variables

// Exercise 1: Declare and Assign Variables​


let userName = "Alice"; // Declaring a string variable [cite: 7, 8]​
const favoriteNumber = 7; // Declaring a number constant ​
[Link]("User Name:", userName); ​
[Link]("Favorite Number:", favoriteNumber); ​

Exercise 2: Basic Arithmetic Operations


// Exercise 2: Basic Arithmetic Operations​
let num1 = 10; ​
let num2 = 5; ​
let sum = num1 + num2; ​
let difference = num1 - num2; ​
let product = num1 * num2; ​
let quotient = num1 / num2; ​
[Link]("Sum:", sum); ​
[Link]("Difference:", difference); ​
[Link]("Product:", product); ​
[Link]("Quotient:", quotient); ​

Exercise 3: String Concatenation


// Exercise 3: String Concatenation​
let firstName = "John"; ​
let lastName = "Doe"; ​
// Method 1: Using the + operator​
let fullName = firstName + " " + lastName; ​
[Link]("Full Name (using +):", fullName); ​
// Method 2: Using template literals (recommended for complex strings)​
let fullGreeting = `Hello, my name is ${firstName} ${lastName}!`; ​
[Link]("Full Greeting (using template literal):", fullGreeting); ​

Exercise 4: Conditional Statement (If/Else)

Laurence Svekis Learn More [Link]


// Exercise 4: Conditional Statement (If/Else)​
let age = 20; ​
// Try changing this value to 16, 18, 25​
if (age >= 18) {​
[Link]("You are an adult."); ​
} else {​
[Link]("You are a minor."); ​
}​
let anotherAge = 16; ​
if (anotherAge >= 18) {​
[Link]("You are an adult. (for anotherAge)"); ​
} else {​
[Link]("You are a minor. (for anotherAge)"); ​
}​

Exercise 5: Conditional Statement (If/Else If/Else)


// Exercise 5: Conditional Statement (If/Else If/Else)​
let score = 85; ​
// Try changing this value (e.g., 95, 72, 55)​
let grade; ​
if (score >= 90) {​
grade = "A"; ​
} else if (score >= 80) {​
grade = "B"; ​
} else if (score >= 70) {​
grade = "C"; ​
} else if (score >= 60) {​
grade = "D";​
} else {​
grade = "F"; ​
}​
[Link](`With a score of ${score}, your grade is: ${grade}`); ​

Exercise 6: For Loop (Basic Iteration)


// Exercise 6: For Loop (Basic Iteration)​

Laurence Svekis Learn More [Link]


[Link]("Numbers from 1 to 10:"); ​
for (let i = 1; i <= 10; i++) {​
[Link](i); ​
}​

Exercise 7: While Loop (Conditional Iteration)


// Exercise 7: While Loop (Conditional Iteration)​
let count = 5; ​
[Link]("Countdown from 5:");​
while (count >= 1) {​
[Link](count); ​
count--; // Decrement count by 1 ​
}​
[Link]("Blast off!"); ​

Exercise 8: Simple Function Definition and Call


// Exercise 8: Simple Function Definition and Call​
function greet(name) {​
[Link](`Hello, ${name}!`); ​
}​
// Call the function​
greet("Alice"); ​
greet("Bob"); ​
greet("Charlie"); ​

Exercise 9: Function with Return Value


// Exercise 9: Function with Return Value​
function addNumbers(a, b) {​
return a + b; ​
}​
// Call the function and store its result​
let result1 = addNumbers(5, 3); ​
[Link]("Sum of 5 and 3:", result1); // Expected: 8 ​
let result2 = addNumbers(100, 20);​

Laurence Svekis Learn More [Link]


[Link]("Sum of 100 and 20:", result2); ​
// Expected: 120​

Exercise 10: Introduction to Arrays


// Exercise 10: Introduction to Arrays​
let fruits = ["Apple", "Banana", "Orange"]; ​
[Link]("Original fruits array:", fruits); ​
// Accessing elements by index (arrays are zero-indexed)​
[Link]("First fruit:", fruits[0]); // "Apple" ​
[Link]("Second fruit:", fruits[1]); ​
// "Banana"​
[Link]("Third fruit:", fruits[2]); // "Orange" ​
// Accessing the last element using .length property​
[Link]("Last fruit:", fruits[[Link] - 1]); ​
// "Orange"​
// Adding an element to the end of the array​
[Link]("Grape"); ​
[Link]("Fruits array after adding 'Grape':", fruits); ​
[Link]("New last fruit:", fruits[[Link] - 1]); // "Grape" ​
[Link]("Total number of fruits:", [Link]); // 4 ​

Exercise 11: Iterating Over an Array with For Loop


// Exercise 11: Iterating Over an Array with For Loop​
let numbers = [10, 20, 30, 40, 50]; ​
[Link]("Numbers in the array:"); ​
for (let i = 0; i < [Link]; i++) {​
[Link](numbers[i]); ​
}​

Exercise 12: Iterating Over an Array with For...of Loop


// Exercise 12: Iterating Over an Array with For...of Loop​
let numbers = [10, 20, 30, 40, 50]; ​
[Link]("Numbers in the array (using for...of):"); ​
for (let number of numbers) { // 'number' here directly gets each element's value​

Laurence Svekis Learn More [Link]


[Link](number); ​
}​

Exercise 13: Array Method: forEach()


// Exercise 13: Array Method: forEach()​
let names = ["Alice", "Bob", "Charlie"]; ​
[Link]("Greetings:"); ​
[Link](function(name) { // The function here is a "callback"​
[Link](`Hello, ${name}!`);​
}); ​
// Using arrow function syntax (more common in modern JS)​
[Link]("\nGreetings (using arrow function):"); ​
[Link](name => {​
[Link](`Hi there, ${name}.`); ​
});​

Exercise 14: Object Basics


// Exercise 14: Object Basics​
let person = {​
name: "John Doe",​
age: 30,​
isStudent: false,​
"favorite color": "blue" // Property with a space in its name​
}; ​
[Link]("Person's details:"); ​
[Link]("Name:", [Link]); // Accessing with dot notation ​
[Link]("Age:", person["age"]); // Accessing with bracket notation ​
[Link]("Is Student:", [Link]); ​
// Accessing property with a space in its name (only bracket notation works)​
[Link]("Favorite Color:", person["favorite color"]); ​
// Modifying a property​
[Link] = 31; ​
[Link]("Updated Age:", [Link]); // Adding a new property ​
[Link] = "New York"; ​
[Link]("City:", [Link]);​

Laurence Svekis Learn More [Link]


[Link]("Updated Person object:", person); ​

Exercise 15: Function with Object as Argument


// Exercise 15: Function with Object as Argument​
function displayBookInfo(book) {​
[Link](`Book: ${[Link]} by ${[Link]}`); ​
}​
// Optional: Using object destructuring in function parameters​
function displayBookInfoDestructured({ title, author }) {​
[Link](`Book (destructured): ${title} by ${author}`); ​
}​
let myBook = {​
title: "The Great Gatsby",​
author: "F. Scott Fitzgerald",​
year: 1925​
}; ​
let anotherBook = {​
title: "1984",​
author: "George Orwell",​
pages: 328​
};​
displayBookInfo(myBook); ​
displayBookInfo(anotherBook); ​
// Even if 'pages' is present, function only uses 'title' and 'author'​
displayBookInfoDestructured(myBook); ​

Exercise 16: Array of Objects


// Exercise 16: Array of Objects​
let students = [​
{ name: "Alice", grade: 92 },​
{ name: "Bob", grade: 78 },​
{ name: "Charlie", grade: 85 },​
{ name: "Diana", grade: 60 }​
]; ​
[Link]("Student Grades:"); ​

Laurence Svekis Learn More [Link]


for (let student of students) {​
[Link](`${[Link]}: ${[Link]}`);​
}​
// Using forEach​
[Link]("\nStudent Grades (using forEach):"); ​
[Link](student => {​
[Link](`- ${[Link]} got a ${[Link]}`); ​
});​

Exercise 17: Basic String Methods


// Exercise 17: Basic String Methods​
let message = "Hello JavaScript World"; ​
[Link]("Original Message:", message); ​
[Link]("Length of message:", [Link]); // 22 ​
[Link]("Uppercase:", [Link]()); // "HELLO JAVASCRIPT WORLD" ​
[Link]("Lowercase:", [Link]()); ​
// "hello javascript world"​
// Finding the index of a substring​
let jsIndex = [Link]("JavaScript"); ​
[Link]("Index of 'JavaScript':", jsIndex); ​
// 6 (index where 'J' starts)​
// Extracting a substring using slice()​
// slice(startIndex, endIndex - 1)​
let extractedWord = [Link](jsIndex, jsIndex + "JavaScript".length); ​
[Link]("Extracted word:", extractedWord); // "JavaScript" ​
// Check if a string includes a substring​
[Link]("Does message include 'World'?", [Link]("World")); ​
// true​

Exercise 18: Function to Reverse a String


// Exercise 18: Function to Reverse a String​
function reverseString(str) {​
let reversedStr = ""; ​
for (let i = [Link] - 1; i >= 0; i--) {​
reversedStr += str[i]; ​

Laurence Svekis Learn More [Link]


// Append character to the reversed string​
}​
return reversedStr; ​
}​
// Alternative using array methods (more advanced, but common)​
function reverseStringMethod(str) {​
return [Link]('').reverse().join(''); ​
}​
[Link]("Reversed 'hello':", reverseString("hello")); // Expected: "olleh" ​
[Link]("Reversed 'world':", reverseString("world")); // Expected: "dlrow" ​
[Link]("Reversed 'JavaScript':", reverseString("JavaScript")); ​
// Expected: "tpircSavaJ"​
[Link]("Reversed 'hello' (method):", reverseStringMethod("hello")); ​

Exercise 19: Find the Largest Number in an Array


// Exercise 19: Find the Largest Number in an Array​
function findLargestNumber(numbers) {​
if ([Link] === 0) {​
return undefined; ​
// Or throw an error, or return a specific value​
}​
let largest = numbers[0]; ​
// Assume the first element is the largest initially​
for (let i = 1; i < [Link]; i++) { // Start from the second element​
if (numbers[i] > largest) {​
largest = numbers[i]; ​
// Update largest if current number is greater​
}​
}​
return largest; ​
}​
[Link]("Largest in [3, 8, 1, 12, 5]:", findLargestNumber([3, 8, 1, 12, 5])); ​
// Expected: 12​
[Link]("Largest in [100, 20, 30]:", findLargestNumber([100, 20, 30])); //
Expected: 100 ​
[Link]("Largest in [7]:", findLargestNumber([7])); ​
// Expected: 7​

Laurence Svekis Learn More [Link]


[Link]("Largest in []:", findLargestNumber([])); // Expected: undefined (due to
added check) ​

Exercise 20: Calculate the Sum of Array Elements


// Exercise 20: Calculate the Sum of Array Elements​
function calculateSum(numbers) {​
let totalSum = 0; ​
// Initialize sum to zero​
for (let i = 0; i < [Link]; i++) {​
totalSum += numbers[i]; ​
// Add current number to totalSum​
}​
return totalSum; ​
}​
// Alternative using for...of loop​
function calculateSumForOf(numbers) {​
let totalSum = 0; ​
for (let num of numbers) {​
totalSum += num;​
}​
return totalSum; ​
}​
// Alternative using reduce() (more advanced)​
function calculateSumReduce(numbers) {​
return [Link]((accumulator, currentValue) => accumulator + currentValue,
0); ​
}​
[Link]("Sum of [1, 2, 3, 4, 5]:", calculateSum([1, 2, 3, 4, 5])); ​
// Expected: 15​
[Link]("Sum of [10, 20, 30]:", calculateSumForOf([10, 20, 30])); // Expected: 60 ​
[Link]("Sum of []:", calculateSum([])); ​
// Expected: 0​
[Link]("Sum of [7, 8, 9] (reduce):", calculateSumReduce([7, 8, 9])); // Expected: 24 ​

Exercise 21: Array Method: filter()

Laurence Svekis Learn More [Link]


// Exercise 21: Array Method: filter()​
let data = [10, 25, 30, 45, 50, 65, 5, 80]; ​
// Filter numbers greater than 40​
let greaterThan40 = [Link](function(number) {​
return number > 40;​
}); ​
[Link]("Numbers greater than 40:", greaterThan40); // Expected: [45, 50, 65, 80] ​
// Using arrow function syntax​
let evenNumbers = [Link](number => number % 2 === 0); ​
[Link]("Even numbers:", evenNumbers); // Expected: [10, 30, 50, 80] ​
// Filtering objects in an array​
let products = [​
{ name: "Laptop", price: 1200 },​
{ name: "Mouse", price: 25 },​
{ name: "Keyboard", price: 75 },​
{ name: "Monitor", price: 300 }​
]; ​
let expensiveProducts = [Link](product => [Link] > 100);​
[Link]("Expensive products (> $100):", expensiveProducts); ​
// Expected: [{ name: "Laptop", price: 1200 }, { name: "Monitor", price: 300 }]​

Exercise 22: Array Method: map()


// Exercise 22: Array Method: map()​
let prices = [10, 20, 30, 45]; ​
// Double each price​
let doubledPrices = [Link](function(price) {​
return price * 2;​
});​
[Link]("Doubled prices:", doubledPrices); ​
// Expected: [20, 40, 60, 90]​
// Using arrow function syntax​
let pricesWithTax = [Link](price => price * 1.05); ​
// Add 5% tax​
[Link]("Prices with 5% tax:", pricesWithTax); // Mapping an array of objects to
get specific properties ​
let users = [​
{ id: 1, name: "Alice", email: "alice@[Link]" },​

Laurence Svekis Learn More [Link]


{ id: 2, name: "Bob", email: "bob@[Link]" },​
{ id: 3, name: "Charlie", email: "charlie@[Link]" }​
]; ​
let userNames = [Link](user => [Link]);​
[Link]("User names:", userNames); // Expected: ["Alice", "Bob", "Charlie"] ​

Exercise 23: Array Method: reduce()


// Exercise 23: Array Method: reduce()​
let items = [5, 10, 15, 20]; ​
// Summing all numbers in an array​
let sum = [Link](function(accumulator, currentValue) {​
[Link](`Accumulator: ${accumulator}, Current Value: ${currentValue}`);​
return accumulator + currentValue;​
}, 0); ​
// 0 is the initial value for the accumulator​
[Link]("Sum of items:", sum); ​
// Expected: 50​
// Using arrow function syntax (common)​
let product = [Link]((acc, val) => acc * val, 1); ​
// Initial value for product is 1​
[Link]("Product of items:", product); ​
// Expected: 5 * 10 * 15 * 20 = 15000​
// Reducing an array of objects to a single value​
let cart = [​
{ item: "Shirt", price: 25 },​
{ item: "Jeans", price: 60 },​
{ item: "Socks", price: 10 }​
]; ​
let totalCartPrice = [Link]((total, currentItem) => total + [Link], 0);​
[Link]("Total cart price:", totalCartPrice); ​
// Expected: 95​

Exercise 24: Closures


// Exercise 24: Closures​
function makeCounter() {​

Laurence Svekis Learn More [Link]


let count = 0; ​
// 'count' is in the outer function's scope​
return function() { // This inner function forms a closure​
count++; ​
// It "remembers" and can access 'count' from its lexical environment​
return count;​
}; ​
}​
let counter1 = makeCounter(); // counter1 is now the inner function returned by
makeCounter()​
[Link]("Counter 1:");​
[Link](counter1()); ​
// Expected: 1​
[Link](counter1()); // Expected: 2 ​
[Link](counter1()); // Expected: 3 ​
let counter2 = makeCounter(); ​
// A new, independent counter​
[Link]("\nCounter 2:");​
[Link](counter2()); // Expected: 1 (starts fresh) ​
[Link](counter1()); ​
// Expected: 4 (counter1 continues independently)​

Exercise 25: Basic Object-Oriented Programming


(Constructor Function / Class)
// Exercise 25: Basic Object-Oriented Programming (Constructor Function)​
// Using a Constructor Function (traditional ES5 way)​
function Car(make, model) {​
[Link] = make; ​
[Link] = model;​
}​
// Add a method to the Car's prototype​
// This ensures all instances share the same method, saving memory​
[Link] = function() {​
[Link](`This is a ${[Link]} ${[Link]}.`); ​
};​
// Create instances​
let car1 = new Car("Toyota", "Camry");​

Laurence Svekis Learn More [Link]


let car2 = new Car("Honda", "Civic");​
[Link](); ​
// Expected: "This is a Toyota Camry."​
[Link](); // Expected: "This is a Honda Civic." ​
// --- Using ES6 Class Syntax (modern way, syntactic sugar over prototypes) ---​
class Motorcycle {​
constructor(brand, type) {​
[Link] = brand; ​
[Link] = type;​
}​
displayDetails() {​
[Link](`This is a ${[Link]} ${[Link]} motorcycle.`); ​
}​
}​
let moto1 = new Motorcycle("Harley-Davidson", "Sportster");​
let moto2 = new Motorcycle("Kawasaki", "Ninja");​
[Link]();​
[Link](); ​

Exercise 26: Asynchronous JavaScript - Callbacks


(Simulated)
// Exercise 26: Asynchronous JavaScript - Callbacks (Simulated)​
function fetchUserData(userId, callback) {​
[Link](`Fetching data for user ID: ${userId}...`); ​
// Simulate an asynchronous operation (e.g., network request)​
setTimeout(() => {​
const user = {​
id: userId,​
name: `User ${userId}`,​
email: `user${userId}@[Link]`​
};​
[Link](`Data for user ${userId} received.`);​
callback(user); // Execute the callback with the fetched data​
}, 2000); ​
// Simulate a 2-second delay​
}​
// How to use it:​

Laurence Svekis Learn More [Link]


[Link]("Starting data fetch for User 1."); ​
fetchUserData(1, function(user) {​
[Link]("Processing fetched user data:");​
[Link]("User Name:", [Link]);​
[Link]("User Email:", [Link]);​
}); ​
[Link]("\nStarting data fetch for User 2.");​
fetchUserData(2, (user) => { // Using arrow function for callback​
[Link]("Processing fetched user data for User 2:");​
[Link]("User ID:", [Link]);​
}); ​
[Link]("Requests initiated. This message appears first because the fetch is
async."); ​
// The "Requests initiated..." message will appear immediately,​
// before the "Data received" messages, demonstrating asynchronicity.​

Exercise 27: Asynchronous JavaScript - Promises


(Basic)
// Exercise 27: Asynchronous JavaScript - Promises (Basic)​
function fetchUserDataPromise(userId) {​
[Link](`(Promise) Fetching data for user ID: ${userId}...`); ​
return new Promise((resolve, reject) => { // A Promise takes a function with resolve
and reject​
setTimeout(() => {​
if (userId === 0) {​
reject("User with ID 0 not found."); // Simulate an error​
return;​
}​
const user = {​
id: userId,​
name: `Promise User ${userId}`,​
status: "active"​
};​
[Link](`(Promise) Data for user ${userId} received.`);​
resolve(user); // Resolve the promise with the user data​
}, 2000);​
}); ​

Laurence Svekis Learn More [Link]


}​
// Using the Promise:​
[Link]("--- Fetching User 1 (Success Case) ---"); ​
fetchUserDataPromise(1)​
.then((user) => { // .then() is called when the promise resolves​
[Link]("Success! User 1 Data:", user);​
[Link](`Resolved User 1 Name: ${[Link]}`);​
})​
.catch((error) => { // .catch() is called when the promise rejects​
[Link]("Error fetching User 1:", error);​
}); ​
[Link]("\n--- Fetching User 0 (Error Case) ---"); ​
fetchUserDataPromise(0)​
.then((user) => {​
[Link]("Success! User 0 Data:", user); // This block will NOT execute​
})​
.catch((error) => {​
[Link]("Error fetching User 0:", error); // This block WILL execute​
}); ​
[Link]("Promise requests initiated. This message appears first."); ​

Exercise 28: Recursion - Factorial Calculation


// Exercise 28: Recursion - Factorial Calculation​
function factorial(n) {​
// Base case: When to stop the recursion​
if (n === 0 || n === 1) {​
return 1; ​
}​
// Recursive step: Call the function itself with a smaller problem​
else {​
return n * factorial(n - 1); ​
}​
}​
[Link]("Factorial of 0:", factorial(0)); // Expected: 1 ​
[Link]("Factorial of 1:", factorial(1)); // Expected: 1 ​
[Link]("Factorial of 5:", factorial(5)); ​
// Expected: 120 (5 * 4 * 3 * 2 * 1)​

Laurence Svekis Learn More [Link]


[Link]("Factorial of 7:", factorial(7)); ​
// Expected: 5040​
// [Link]("Factorial of -1:", factorial(-1)); // This would lead to infinite recursion
without proper handling​

Exercise 29: Higher-Order Function - map() with


Objects
// Exercise 29: Higher-Order Function - map() with Objects​
let products = [​
{ id: 1, name: "Laptop", price: 1200, category: "Electronics" },​
{ id: 2, name: "Mouse", price: 25, category: "Electronics" },​
{ id: 3, name: "Notebook", price: 15, category: "Stationery" },​
{ id: 4, name: "Desk Chair", price: 250, category: "Furniture" }​
]; ​
// Add a priceWithTax property to each product​
const TAX_RATE = 0.15; ​
let productsWithTax = [Link](product => {​
return {​
...product, // Copies all existing properties from the original product object​
priceWithTax: [Link] * (1 + TAX_RATE) // Adds the new property​
};​
}); ​
[Link]("Products with Tax:", productsWithTax); ​
/* Expected Output Structure (approx):​
[​
{ id: 1, name: "Laptop", price: 1200, category: "Electronics", priceWithTax: 1380 },​
{ id: 2, name: "Mouse", price: 25, category: "Electronics", priceWithTax: 28.75 },​
...​
] */​
// Transform products into a simplified list for display​
let productTitles = [Link](product => `${[Link]} ($${[Link]})`); ​
[Link]("\nProduct Titles:", productTitles); // Expected: ["Laptop ($1200)", "Mouse
($25)", ...] ​

Exercise 30: Chaining Array Methods

Laurence Svekis Learn More [Link]


// Exercise 30: Chaining Array Methods​
let transactions = [​
{ id: 1, amount: 100, type: 'credit', date: '2023-01-01' },​
{ id: 2, amount: 50, type: 'debit', date: '2023-01-02' },​
{ id: 3, amount: 200, type: 'credit', date: '2023-01-03' },​
{ id: 4, amount: 30, type: 'debit', date: '2023-01-04' },​
{ id: 5, amount: 150, type: 'credit', date: '2023-01-05' }​
]; ​
// Calculate the total amount of all credit transactions​
let totalCreditAmount = transactions​
.filter(transaction => [Link] === 'credit') // Step 1: Filter credit transactions ​
.map(creditTransaction => [Link]) // Step 2: Extract amounts ​
.reduce((sum, amount) => sum + amount, 0); ​
// Step 3: Sum the amounts​
[Link]("Transactions:", transactions);​
[Link]("Total Credit Amount:", totalCreditAmount); ​
// Expected: 100 + 200 + 150 = 450​
// Another example: Get names of users older than 25​
let people = [​
{ name: "Alice", age: 20 },​
{ name: "Bob", age: 30 },​
{ name: "Charlie", age: 25 },​
{ name: "Diana", age: 35 }​
]; ​
let namesOfAdults = people​
.filter(person => [Link] > 25)​
.map(adult => [Link]); ​
[Link]("\nNames of people older than 25:", namesOfAdults); // Expected: ["Bob",
"Diana"] ​

Exercise 31: Error Handling with try...catch


// Exercise 31: Error Handling with try...catch​
function divide(a, b) {​
try {​
if (b === 0) {​
throw new Error("Cannot divide by zero."); ​
// Throw an error if b is 0​

Laurence Svekis Learn More [Link]


}​
return a / b; ​
// Perform division if b is not 0​
} catch (error) {​
[Link]("An error occurred:", [Link]); ​
// Catch and log the error message​
return NaN; ​
// Return Not-a-Number or some other indicative value​
}​
}​
[Link]("10 / 2 =", divide(10, 2)); ​
// Expected: 5​
[Link]("7 / 0 =", divide(7, 0)); // Expected: An error message and NaN ​
[Link]("15 / 3 =", divide(15, 3)); ​
// Expected: 5​

Exercise 32: Understanding this Keyword Context


// Exercise 32: Understanding 'this' Keyword Context​
let calculator = {​
value: 0, // Initial value​
// Method to add a number to the current value​
add: function(num) {​
[Link] += num; ​
// 'this' refers to the 'calculator' object​
return this; ​
// Return 'this' to allow method chaining​
},​
// Method to get the current result​
getResult: function() {​
return [Link]; ​
// 'this' refers to the 'calculator' object​
},​
// Example of 'this' context changing inside a regular function​
// (This will be clarified with arrow functions later)​
debugValueLater: function() {​
setTimeout(function() {​
// [Link]("Value inside setTimeout (problematic 'this'):", [Link]);​

Laurence Svekis Learn More [Link]


// In strict mode (default for modules), 'this' here would be undefined.​
// In non-strict mode (old browsers), 'this' would be the global object
(window/global).​
// This highlights why arrow functions are often preferred for callbacks.​
}, 100); ​
}​
};​
// Demonstrate method chaining​
let finalResult = [Link](5).add(10).add(20).getResult();​
[Link]("Chained result:", finalResult); ​
// Expected: 35​
// Reset and try another sequence​
[Link] = 0; ​
// Reset for a new calculation​
let anotherResult = [Link](2).add(3).getResult();​
[Link]("Another result:", anotherResult); ​
// Expected: 5​

Exercise 33: Arrow Functions (=>)


// Exercise 33: Arrow Functions (=>)​
// Example 1: `forEach` with arrow function​
let numbers = [1, 2, 3, 4, 5]; ​
[Link]("Numbers via forEach (arrow function):");​
[Link](num => [Link](num * 2)); ​
// Concise syntax for single expression​
// Example 2: `map` with arrow function​
let names = ["Alice", "Bob", "Charlie"]; ​
let uppercasedNames = [Link](name => [Link]());​
[Link]("Uppercased names (arrow function):", uppercasedNames); ​
// Example 3: Arrow functions and `this` binding (lexical `this`)​
let person = {​
name: "John Doe",​
// Regular function for method definition​
greetDelayed: function() {​
[Link](`Hello from ${[Link]}!`); ​
// 'this' correctly refers to 'person'​
// Using an arrow function for the setTimeout callback​

Laurence Svekis Learn More [Link]


// Arrow functions do NOT bind their own 'this'.​
// They inherit 'this' from the enclosing (lexical) scope.​
setTimeout(() => {​
[Link](`Delayed greeting from ${[Link]}.`); // 'this' still refers to 'person'​
}, 1000); ​
// For comparison: if you used a regular function here, 'this' would be different​
setTimeout(function() {​
// [Link](`Problematic delayed greeting from ${[Link]}.`);​
// 'this' would be 'window' or 'undefined' in strict mode​
}, 1200); ​
}​
};​
[Link](); ​

Exercise 34: Object Destructuring


// Exercise 34: Object Destructuring​
let movie = {​
title: "Inception",​
director: "Christopher Nolan",​
year: 2010,​
rating: 8.8​
}; ​
// 1. Basic destructuring​
const { title, director } = movie;​
[Link]("Title:", title); // Expected: Inception ​
[Link]("Director:", director); ​
// Expected: Christopher Nolan​
// 2. Destructuring with renaming​
const { year, rating: imdbRating } = movie;​
[Link]("Year:", year); ​
// Expected: 2010​
[Link]("IMDB Rating:", imdbRating); // Expected: 8.8 (using new variable name) ​
// 3. Destructuring with default values for non-existent properties​
const { genre = "Sci-Fi", producer = "Unknown" } = movie; ​
[Link]("Genre (with default):", genre); // Expected: Sci-Fi ​
[Link]("Producer (with default):", producer); ​
// Expected: Unknown​

Laurence Svekis Learn More [Link]


// Destructuring in function parameters (common use case)​
function displayMovieDetails({ title, director, year, runtime = "N/A" }) {​
[Link](`\nDetails: ${title} (${year}) by ${director}. Runtime: ${runtime}`); ​
}​
displayMovieDetails(movie);​
displayMovieDetails({ title: "Avatar", director: "James Cameron", year: 2009 }); ​
// No runtime provided​

Exercise 35: Array Destructuring


// Exercise 35: Array Destructuring​
let rgb = ["red", "green", "blue", "alpha", "cyan"]; ​
// 1. Basic destructuring​
const [firstColor, secondColor] = rgb;​
[Link]("First color:", firstColor); // Expected: red ​
[Link]("Second color:", secondColor); ​
// Expected: green​
// 2. Skipping elements​
const [, , thirdColor] = rgb; ​
// Skip first two elements with empty commas​
[Link]("Third color:", thirdColor); ​
// Expected: blue​
// 3. Rest pattern: collects remaining elements into a new array​
const [primaryColor, ...otherColors] = rgb; ​
[Link]("Primary Color:", primaryColor); // Expected: red ​
[Link]("Other Colors:", otherColors); // Expected: ["green", "blue", "alpha",
"cyan"] ​
// Destructuring with default values​
const [color1, color2, color3, color4, color5 = "magenta"] = rgb; ​
[Link]("Color 5 (with default):", color5); // Expected: magenta (if not enough
elements) ​
// Swapping variables easily with destructuring​
let x = 10; ​
let y = 20;​
[x, y] = [y, x]; // Swap x and y without a temporary variable​
[Link](`\nSwapped: x = ${x}, y = ${y}`); ​
// Expected: x = 20, y = 10​

Laurence Svekis Learn More [Link]


Exercise 36: Spread Operator (...) - Arrays
// Exercise 36: Spread Operator (...) - Arrays​
let arr1 = [1, 2, 3]; ​
let arr2 = [4, 5, 6]; ​
// 1. Combining arrays​
let combinedArr = [...arr1, ...arr2];​
[Link]("Combined Array:", combinedArr); ​
// Expected: [1, 2, 3, 4, 5, 6]​
let moreCombined = [0, ...arr1, 10, ...arr2, 7];​
[Link]("More Combined:", moreCombined); ​
// Expected: [0, 1, 2, 3, 10, 4, 5, 6, 7]​
// 2. Copying arrays (shallow copy)​
let arr1Copy = [...arr1]; ​
[Link]("Array 1 Copy:", arr1Copy); // Expected: [1, 2, 3] ​
// Verify it's a copy (modifying copy doesn't affect original)​
[Link](99); ​
[Link]("Array 1 after copy modified:", arr1); // Expected: [1, 2, 3] ​
[Link]("Array 1 Copy after modification:", arr1Copy); ​
// Expected: [1, 2, 3, 99]​
// 3. Passing array elements as function arguments​
function sumAll(a, b, c) {​
return a + b + c; ​
}​
let numbersForSum = [10, 20, 30];​
[Link]("Sum of numbersForSum (using spread):", sumAll(...numbersForSum)); ​
// Expected: 60​
// Using [Link]() with spread​
let grades = [85, 92, 78, 95, 88];​
[Link]("Max grade:", [Link](...grades)); ​
// Expected: 95​

Exercise 37: Spread Operator (...) - Objects


// Exercise 37: Spread Operator (...) - Objects​
let user = { name: "Jane", age: 28 }; ​
// 1. Copying objects and adding new properties​

Laurence Svekis Learn More [Link]


let userCopy = { ...user, city: "London" }; ​
// Creates a new object, copies properties, adds/overrides 'city'​
[Link]("Original User:", user); ​
// Expected: { name: "Jane", age: 28 }​
[Link]("User Copy:", userCopy); ​
// Expected: { name: "Jane", age: 28, city: "London" }​
// 2. Merging objects​
let address = { street: "123 Main St", zip: "10001" }; ​
let contactInfo = { email: "jane@[Link]", phone: "555-1234" };​
let userProfile = { ...user, ...address, ...contactInfo, occupation: "Engineer" }; ​
[Link]("User Profile (merged):", userProfile); ​
/* Expected: {​
name: "Jane", age: 28, street: "123 Main St",​
zip: "10001", email: "jane@[Link]", phone: "555-1234",​
occupation: "Engineer"​
} */​
// Handling conflicts (later properties override earlier ones)​
let baseSettings = { theme: "dark", fontSize: 16 }; ​
let userSettings = { fontSize: 18, notifications: true };​
let finalSettings = { ...baseSettings, ...userSettings }; ​
[Link]("Final Settings (conflict resolved):", finalSettings); // Expected: { theme:
"dark", fontSize: 18, notifications: true } ​

Exercise 38: Ternary Operator (Conditional Operator)


// Exercise 38: Ternary Operator (Conditional Operator)​
let temperature1 = 30;​
let weatherStatus1 = (temperature1 > 25) ? ​
"Hot" : "Cold";​
[Link](`Temperature: ${temperature1}°C, Status: ${weatherStatus1}`); //
Expected: Hot​
let temperature2 = 18; ​
let weatherStatus2 = (temperature2 > 25) ? "Hot" : "Cold";​
[Link](`Temperature: ${temperature2}°C, Status: ${weatherStatus2}`); ​
// Expected: Cold​
// Another example: Check if a user is logged in​
let isLoggedIn = true; ​
let message = isLoggedIn ? "Welcome back!" : "Please log in.";​

Laurence Svekis Learn More [Link]


[Link](message); // Expected: Welcome back! ​
// Nested ternary (use sparingly for readability)​
let time = 14; ​
// 2 PM​
let greeting = (time < 12) ? "Good morning!" ​
: (time < 18) ? ​
"Good afternoon!" : "Good evening!"; ​
[Link](greeting); // Expected: Good afternoon! ​

Exercise 39: Nullish Coalescing Operator (??)


// Exercise 39: Nullish Coalescing Operator (??)​
let userName1 = null;​
let defaultName = "Guest"; ​
const displayName1 = userName1 ?? defaultName; // Falls back if userName1 is null or
undefined​
[Link]("Display Name 1 (null):", displayName1); ​
// Expected: Guest​
let userName2 = undefined;​
const displayName2 = userName2 ?? defaultName;​
[Link]("Display Name 2 (undefined):", displayName2); ​
// Expected: Guest​
let userName3 = "Alice";​
const displayName3 = userName3 ?? defaultName;​
[Link]("Display Name 3 (value):", displayName3); ​
// Expected: Alice​
// --- Difference between ?? and || ​
// The logical OR (||) operator considers `false`, `0`, `""` (empty string), `null`,
`undefined` as "falsy". ​
// The nullish coalescing operator (??) only considers `null` and `undefined` as
"nullish". ​
let valueZero = 0; ​
let valueEmptyString = ""; ​
let valueFalse = false;​
// Using ||​
[Link]("\n--- Using || (Logical OR) ---"); ​
[Link]("valueZero || 'Default':", valueZero || "Default"); // Expected: Default (0 is
falsy) ​

Laurence Svekis Learn More [Link]


[Link]("valueEmptyString || 'Default':", valueEmptyString || "Default"); ​
// Expected: Default ("" is falsy)​
[Link]("valueFalse || 'Default':", valueFalse || "Default"); ​
// Expected: Default (false is falsy)​
// Using ??​
[Link]("\n--- Using ?? (Nullish Coalescing) ---"); ​
[Link]("valueZero ?? 'Default':", valueZero ?? "Default"); // Expected: 0 (0 is not
nullish) ​
[Link]("valueEmptyString ?? 'Default':", valueEmptyString ?? "Default"); ​
// Expected: "" ("" is not nullish)​
[Link]("valueFalse ?? 'Default':", valueFalse ?? "Default"); ​
// Expected: false (false is not nullish)​

Exercise 40: Optional Chaining (?.)


// Exercise 40: Optional Chaining (?.)​
let user1 = {​
name: "Alice",​
email: "alice@[Link]",​
address: {​
street: "123 Main St",​
city: "Anytown"​
}​
}; ​
let user2 = {​
name: "Bob",​
email: "bob@[Link]"​
// No address property​
}; ​
let user3 = {​
name: "Charlie",​
contact: {​
email: "charlie@[Link]"​
}​
}; ​
// Safely access nested properties using optional chaining​
[Link]("User 1 Street:", [Link]?.street); ​
// Expected: 123 Main St​

Laurence Svekis Learn More [Link]


[Link]("User 2 Street:", [Link]?.street); // Expected: undefined (no error) ​
[Link]("User 1 Zip Code:", [Link]?.zipCode); ​
// Expected: undefined (property doesn't exist)​
// Accessing a potentially non-existent nested object property​
[Link]("User 1 Company Name:", [Link]?.name); ​
// Expected: undefined (no error)​
[Link]("User 2 Company Name:", [Link]?.name); ​
// Expected: undefined (no error)​
// Combining with Nullish Coalescing for a fallback​
let user1City = [Link]?.city ?? "N/A"; ​
let user2City = [Link]?.city ?? "N/A";​
[Link]("User 1 City:", user1City); // Expected: Anytown ​
[Link]("User 2 City:", user2City); ​
// Expected: N/A​
// Optional chaining with function calls​
// If [Link] is undefined, it won't try to call .getEmail()​
const getEmail = (usr) => [Link]?.getEmail?.(); ​
// The method getEmail might not exist​
[Link] = () => "charlie_from_method@[Link]";​
[Link]("User 3 Email (from method):", getEmail(user3)); ​
// Expected: charlie_from_method@[Link]​
[Link] = undefined; // Remove the method​
[Link]("User 3 Email (method removed):", getEmail(user3)); ​
// Expected: undefined (no error)​

Exercise 41: Asynchronous JavaScript - async/await


// Exercise 41: Asynchronous JavaScript - async/await​
// Reusing the Promise-based function from Exercise 27​
function fetchUserDataPromise(userId) {​
return new Promise((resolve, reject) => {​
setTimeout(() => {​
if (userId === 0) {​
reject("User with ID 0 not found.");​
return;​
}​
const user = {​
id: userId,​

Laurence Svekis Learn More [Link]


name: `Async User ${userId}`,​
status: "active"​
};​
resolve(user);​
}, 1500); // Shorter delay for quicker demonstration​
}); ​
}​
// New function using async/await​
async function displayUserAsync(userId) {​
[Link](`\n(async/await) Attempting to fetch user ${userId}...`); ​
try {​
const user = await fetchUserDataPromise(userId); ​
// Pause execution until the promise resolves​
[Link](`(async/await) Successfully fetched user ${userId}:`, user); ​
} catch (error) {​
[Link](`(async/await) Error fetching user ${userId}:`, error); ​
}​
}​
// Demonstrate usage​
displayUserAsync(101); ​
// Success case​
displayUserAsync(0); // Error case ​
displayUserAsync(102); // Another success case ​
[Link]("Main script continues to run while async functions are awaiting."); ​

Exercise 42: Classes and Inheritance


// Exercise 42: Classes and Inheritance​
// Parent Class​
class Shape {​
constructor(color) {​
[Link] = color; ​
}​
displayColor() {​
[Link](`The shape color is ${[Link]}.`); ​
}​
}​
// Child Class inheriting from Shape​

Laurence Svekis Learn More [Link]


class Circle extends Shape {​
constructor(color, radius) {​
super(color); ​
// Call the parent class's constructor​
[Link] = radius; ​
}​
// Override the displayColor method from the parent class​
displayColor() {​
[Link](`The circle color is ${[Link]}.`); ​
}​
// New method specific to Circle​
calculateArea() {​
return [Link] * [Link] * [Link]; ​
}​
}​
// Child Class inheriting from Shape (another example)​
class Rectangle extends Shape {​
constructor(color, width, height) {​
super(color); ​
[Link] = width;​
[Link] = height;​
}​
calculateArea() {​
return [Link] * [Link]; ​
}​
// Overriding a method and calling the super method​
displayColor() {​
[Link](); ​
// Call the parent's displayColor method​
[Link](`This is a rectangle.`); ​
}​
}​
// Create instances​
let genericShape = new Shape("Red");​
[Link](); // Expected: The shape color is Red. ​
let myCircle = new Circle("Blue", 5);​
[Link](); // Expected: The circle color is Blue. (Overridden method) ​
[Link]("Circle Area:", [Link]().toFixed(2)); ​
// Expected: ~78.54​

Laurence Svekis Learn More [Link]


let myRectangle = new Rectangle("Green", 4, 6);​
[Link](); // Expected: The shape color is Green. ​
[Link]("Rectangle Area:", [Link]()); // Expected: 24 ​

Exercise 43: Static Methods and Properties


// Exercise 43: Static Methods and Properties​
class MathHelper {​
// Static property​
static PI = 3.14159; ​
// Static method: can be called directly on the class, not instances​
static add(a, b) {​
return a + b; ​
}​
static multiply(a, b) {​
return a * b; ​
}​
// Instance method (requires an instance of MathHelper)​
instanceMethod() {​
[Link]("This is an instance method."); ​
}​
}​
// Accessing static property​
[Link]("[Link]:", [Link]); // Expected: 3.14159 ​
// Calling static methods​
[Link]("[Link](5, 3):", [Link](5, 3)); ​
// Expected: 8​
[Link]("[Link](4, 6):", [Link](4, 6)); // Expected: 24 ​
// Trying to call a static method on an instance will throw an error​
// let myHelper = new MathHelper();​
// [Link](1, 2); // TypeError: [Link] is not a function​
// Calling an instance method (requires an instance)​
let myHelper = new MathHelper(); ​
[Link](); ​

Exercise 44: Getters and Setters

Laurence Svekis Learn More [Link]


// Exercise 44: Getters and Setters​
class Product {​
constructor(name, initialPrice) {​
[Link] = name; ​
this._price = 0; // Conventionally, _ prefix indicates a private/protected property​
[Link] = initialPrice; ​
// Use the setter to initialize with validation​
}​
// Getter for 'price'​
get price() {​
[Link](`Getting price for ${[Link]}...`); ​
return this._price;​
}​
// Setter for 'price'​
set price(newPrice) {​
[Link](`Attempting to set price for ${[Link]} to ${newPrice}...`); ​
if (typeof newPrice === 'number' && newPrice >= 0) {​
this._price = newPrice; ​
[Link](`Price set successfully to ${newPrice}.`);​
} else {​
[Link](`Error: Invalid price value: ${newPrice}. Price must be a non-negative
number.`); ​
}​
}​
displayDetails() {​
[Link](`${[Link]} - $${[Link](2)}`); ​
}​
}​
let laptop = new Product("Laptop", 1200);​
[Link](); // Getting price... Laptop - $1200.00 ​
[Link]("Laptop price is:", [Link]); ​
// Accessing as a property (invokes getter)​
[Link] = 1250; // Setting price (invokes setter) ​
[Link](); ​
// Getting price... Laptop - $1250.00​
[Link] = -50; // Invalid price (invokes setter, logs error) ​
[Link](); ​
// Still Laptop - $1250.00 (price not changed due to validation)​
[Link] = "one thousand"; ​

Laurence Svekis Learn More [Link]


// Invalid type (invokes setter, logs error)​
[Link](); // Still Laptop - $1250.00 ​

Exercise 45: Array Method: some()


// Exercise 45: Array Method: some()​
let grades = [60, 75, 80, 90, 55, 62]; ​
// Check if at least one grade is >= 90​
let hasExcellentGrade = [Link](grade => grade >= 90); ​
[Link]("Are there any excellent grades (>= 90)?", hasExcellentGrade); //
Expected: true ​
let grades2 = [50, 60, 70, 80]; ​
let hasExcellentGrade2 = [Link](grade => grade >= 90);​
[Link]("Are there any excellent grades (>= 90) in grades2?",
hasExcellentGrade2); ​
// Expected: false​
// Check if any product is out of stock (using objects)​
let products = [​
{ name: "Milk", inStock: true },​
{ name: "Bread", inStock: false },​
{ name: "Eggs", inStock: true }​
]; ​
let anyOutOfStock = [Link](product => ![Link]);​
[Link]("Is any product out of stock?", anyOutOfStock); ​
// Expected: true​
let allInStockProducts = [​
{ name: "Apples", inStock: true },​
{ name: "Bananas", inStock: true }​
]; ​
let anyOutOfStock2 = [Link](product => ![Link]);​
[Link]("Is any product out of stock (all in stock)?", anyOutOfStock2); ​
// Expected: false​

Exercise 46: Array Method: every()


// Exercise 46: Array Method: every()​
let ages = [22, 28, 35, 40, 19]; ​

Laurence Svekis Learn More [Link]


// Check if all ages are >= 18​
let allAdults = [Link](age => age >= 18); ​
[Link]("Are all ages >= 18?", allAdults); // Expected: true ​
let ages2 = [17, 20, 25]; ​
let allAdults2 = [Link](age => age >= 18);​
[Link]("Are all ages >= 18 in ages2?", allAdults2); ​
// Expected: false (due to 17)​
// Check if all tasks are completed​
let tasks = [​
{ id: 1, completed: true },​
{ id: 2, completed: true },​
{ id: 3, completed: false }​
]; ​
let allTasksCompleted = [Link](task => [Link]);​
[Link]("Are all tasks completed?", allTasksCompleted); ​
// Expected: false​
let allDoneTasks = [​
{ id: 1, completed: true },​
{ id: 2, completed: true }​
]; ​
let allTasksCompleted2 = [Link](task => [Link]);​
[Link]("Are all tasks completed (all done)?", allTasksCompleted2); ​
// Expected: true​

Exercise 47: Array Method: find() and findIndex()


// Exercise 47: Array Method: find() and findIndex()​
let users = [​
{ id: 1, name: "Alice", active: true },​
{ id: 2, name: "Bob", active: false },​
{ id: 3, name: "Charlie", active: true },​
{ id: 4, name: "Alice", active: false } // Another Alice​
]; ​
// 1. Using find() to get the first matching element​
let userWithId2 = [Link](user => [Link] === 2); ​
[Link]("User with ID 2:", userWithId2); // Expected: { id: 2, name: "Bob", active:
false } ​
let activeUser = [Link](user => [Link] === true); ​

Laurence Svekis Learn More [Link]


[Link]("First active user:", activeUser); // Expected: { id: 1, name: "Alice", active:
true } ​
// 2. Using findIndex() to get the index of the first matching element​
let charlieIndex = [Link](user => [Link] === "Charlie"); ​
[Link]("Index of Charlie:", charlieIndex); // Expected: 2 ​
let firstAliceIndex = [Link](user => [Link] === "Alice");​
[Link]("Index of first Alice:", firstAliceIndex); ​
// Expected: 0​
// 3. Finding non-existent elements/indices​
let nonExistentUser = [Link](user => [Link] === 99);​
[Link]("Non-existent user:", nonExistentUser); ​
// Expected: undefined​
let nonExistentIndex = [Link](user => [Link] === "David");​
[Link]("Index of non-existent user:", nonExistentIndex); ​
// Expected: -1​

Exercise 48: Set Data Structure


// Exercise 48: Set Data Structure​
const uniqueNumbers = new Set();​
[Link](1); ​
[Link](2); ​
[Link](3);​
[Link](2); // Adding 2 again has no effect as Sets only store unique
values​
[Link](4);​
[Link](1); ​
// Adding 1 again has no effect​
[Link]("Set after adding elements:", uniqueNumbers); ​
// Expected: Set { 1, 2, 3, 4 }​
// 1. Size of the Set​
[Link]("Size of Set:", [Link]); ​
// Expected: 4​
// 2. Check for existence​
[Link]("Does Set contain 3?", [Link](3)); ​
// Expected: true​
[Link]("Does Set contain 5?", [Link](5)); // Expected: false ​
// 3. Remove an element​

Laurence Svekis Learn More [Link]


[Link](2); ​
[Link]("Set after deleting 2:", uniqueNumbers); // Expected: Set { 1, 3, 4 } ​
[Link]("Does Set contain 2 after deletion?", [Link](2)); ​
// Expected: false​
// 4. Iterate over the Set​
[Link]("Elements in Set:"); ​
for (let num of uniqueNumbers) {​
[Link](num);​
}​
// Convert array with duplicates to array with unique elements using Set​
let numbersWithDuplicates = [1, 5, 2, 8, 5, 1, 9, 2]; ​
let uniqueArray = [...new Set(numbersWithDuplicates)]; // Convert to Set, then spread
back to array​
[Link]("Unique array from duplicates:", uniqueArray); ​
// Expected: [1, 5, 2, 8, 9]​

Exercise 49: Map Data Structure


// Exercise 49: Map Data Structure​
const userRoles = new Map(); ​
[Link]("Alice", "Admin"); ​
[Link]("Bob", "Editor");​
[Link]("Charlie", "Viewer");​
[Link]("Map after adding elements:", userRoles); ​
// Expected: Map { 'Alice' => 'Admin', 'Bob' => 'Editor', 'Charlie' => 'Viewer' }​
// 1. Get a value by key​
[Link]("Role of Alice:", [Link]("Alice")); ​
// Expected: Admin​
// 2. Check if a key exists​
[Link]("Does David exist?", [Link]("David")); ​
// Expected: false​
[Link]("Does Alice exist?", [Link]("Alice")); // Expected: true ​
// 3. Update a value​
[Link]("Bob", "Moderator"); ​
[Link]("Updated role of Bob:", [Link]("Bob")); // Expected: Moderator ​
// 4. Delete a key-value pair​
[Link]("Charlie");​
[Link]("Map after deleting Charlie:", userRoles); ​

Laurence Svekis Learn More [Link]


// Expected: Map { 'Alice' => 'Admin', 'Bob' => 'Moderator' }​
// 5. Iterate over the Map​
[Link]("\nIterating Map (entries):"); ​
for (let [name, role] of userRoles) { // Directly destructure key and value​
[Link](`${name}'s role is ${role}`); ​
}​
[Link]("\nIterating Map (keys):");​
for (let name of [Link]()) {​
[Link](`User: ${name}`);​
}​
[Link]("\nIterating Map (values):"); ​
for (let role of [Link]()) {​
[Link](`Role: ${role}`); ​
}​

Exercise 50: localStorage (Basic Persistence)


// Exercise 50: localStorage (Basic Persistence)​
// Check if localStorage is available (it usually is in browsers)​
if (typeof localStorage !== 'undefined') {​
[Link]("localStorage is available."); ​
// 1. Store a string​
[Link]("myUserName", "Sarah");​
[Link]("Stored 'Sarah' in localStorage under 'myUserName'."); ​
// 2. Retrieve a string​
let storedUserName = [Link]("myUserName");​
[Link]("Retrieved 'myUserName':", storedUserName); ​
// Expected: Sarah​
// 3. Store an object (must be stringified)​
let settingsObject = {​
theme: "dark",​
notifications: true,​
fontSize: 16​
}; ​
[Link]("userSettings", [Link](settingsObject));​
[Link]("Stored settings object (stringified) under 'userSettings'.");​
// 4. Retrieve and parse the object​
let storedSettingsString = [Link]("userSettings"); ​

Laurence Svekis Learn More [Link]


if (storedSettingsString) {​
let parsedSettings = [Link](storedSettingsString);​
[Link]("Retrieved and parsed 'userSettings':", parsedSettings); ​
// Expected: { theme: 'dark', notifications: true, fontSize: 16 }​
[Link]("Theme from settings:", [Link]); ​
} else {​
[Link]("No 'userSettings' found in localStorage."); ​
}​
// 5. Remove an item​
[Link]("myUserName");​
[Link]("Removed 'myUserName' from localStorage."); ​
[Link]("Attempting to retrieve 'myUserName' after removal:",
[Link]("myUserName")); // Expected: null​
// You can also clear all items (use with caution!)​
// [Link]();​
// [Link]("All localStorage cleared.");​
} else {​
[Link]("localStorage is not available in this environment."); ​
}​

Exercise 51: Palindrome Checker


// Exercise 51: Palindrome Checker​
function isPalindrome(str) {​
// Step 1: Clean the string - convert to lowercase and remove non-alphanumeric
characters​
const cleanedStr = [Link]().replace(/[^a-z0-9]/g, ''); ​
// Step 2: Reverse the cleaned string​
const reversedStr = [Link]('').reverse().join(''); ​
// Step 3: Compare the cleaned string with its reversed version​
return cleanedStr === reversedStr; ​
}​
[Link]("'racecar' is a palindrome:", isPalindrome("racecar")); // Expected: true ​
[Link]("'hello' is a palindrome:", isPalindrome("hello")); ​
// Expected: false​
[Link]("'Madam' is a palindrome:", isPalindrome("Madam")); // Expected: true
(case-insensitive) ​
[Link]("'A man, a plan, a canal: Panama' is a palindrome:", isPalindrome("A man,

Laurence Svekis Learn More [Link]


a plan, a canal: Panama")); ​
// Expected: true (ignores non-alphanumeric)​
[Link]("'' is a palindrome:", isPalindrome("")); ​
// Expected: true (empty string is a palindrome)​
[Link]("'A' is a palindrome:", isPalindrome("A")); ​
// Expected: true (single character is a palindrome)​

Exercise 52: Anagram Checker


// Exercise 52: Anagram Checker​
function cleanAndSortString(str) {​
return str​
.toLowerCase() // Convert to lowercase​
.replace(/[^a-z0-9]/g, '') // Remove non-alphanumeric characters​
.split('') // Split into an array of characters​
.sort() // Sort the characters alphabetically​
.join(''); // Join back into a string ​
}​
function areAnagrams(str1, str2) {​
// Anagrams must have the same length after cleaning​
if ([Link] !== [Link]) {​
return false; ​
}​
return cleanAndSortString(str1) === cleanAndSortString(str2);​
}​
[Link]("'listen' and 'silent' are anagrams:", areAnagrams("listen", "silent")); ​
// Expected: true​
[Link]("'Debit Card' and 'Bad Credit' are anagrams:", areAnagrams("Debit Card",
"Bad Credit")); ​
// Expected: true (ignores case and spaces)​
[Link]("'hello' and 'world' are anagrams:", areAnagrams("hello", "world")); ​
// Expected: false​
[Link]("'Anagram' and 'Nag A Ram' are anagrams:", areAnagrams("Anagram",
"Nag A Ram")); ​
// Expected: true​
[Link]("'' and '' are anagrams:", areAnagrams("", "")); // Expected: true ​
[Link]("'a' and 'b' are anagrams:", areAnagrams("a", "b")); ​
// Expected: false​

Laurence Svekis Learn More [Link]


Exercise 53: FizzBuzz
// Exercise 53: FizzBuzz​
function fizzBuzz(countTo) {​
[Link](`FizzBuzz up to ${countTo}:`); ​
for (let i = 1; i <= countTo; i++) {​
let output = ""; ​
if (i % 3 === 0) { // Check if divisible by 3​
output += "Fizz"; ​
}​
if (i % 5 === 0) { // Check if divisible by 5​
output += "Buzz"; ​
}​
// If output is empty, it means it's not divisible by 3 or 5​
[Link](output || i); ​
// Use || to print number if output is empty​
}​
}​
fizzBuzz(15); ​
// Will print up to 15 to demonstrate​

Exercise 54: Remove Duplicates from an Array


// Exercise 54: Remove Duplicates from an Array​
function removeDuplicates(arr) {​
// The most concise and often preferred way using Set​
return [...new Set(arr)]; ​
}​
// Alternative using filter and indexOf (less efficient for large arrays)​
function removeDuplicatesLegacy(arr) {​
return [Link]((item, index) => [Link](item) === index); ​
}​
[Link]("Remove duplicates from [1, 2, 2, 3, 4, 4, 5]:", removeDuplicates([1, 2, 2, 3,
4, 4, 5])); ​
// Expected: [1, 2, 3, 4, 5]​
[Link]("Remove duplicates from ['apple', 'banana', 'apple', 'orange']:",

Laurence Svekis Learn More [Link]


removeDuplicates(['apple', 'banana', 'apple', 'orange'])); ​
// Expected: ['apple', 'banana', 'orange']​
[Link]("Remove duplicates from [1, '1', 2, 1]:", removeDuplicates([1, '1', 2, 1])); ​
// Expected: [1, '1', 2] (Set distinguishes types)​
[Link]("Remove duplicates from []:", removeDuplicates([])); ​
// Expected: []​
[Link]("Remove duplicates from ['a', 'b', 'c']:", removeDuplicates(['a', 'b', 'c'])); //
Expected: ['a', 'b', 'c'] ​
[Link]("\nUsing legacy method:"); ​
[Link]("Remove duplicates from [1, 2, 2, 3, 4, 4, 5]:", removeDuplicatesLegacy([1,
2, 2, 3, 4, 4, 5])); ​

Exercise 55: Count Character Occurrences


// Exercise 55: Count Character Occurrences​
function countChars(str) {​
const charCounts = {}; ​
// Initialize an empty object to store counts​
const cleanedStr = [Link](); ​
// Convert to lowercase for case-insensitivity​
for (let i = 0; i < [Link]; i++) {​
const char = cleanedStr[i]; ​
// Only count alphanumeric characters (optional, but good practice for practical
use)​
if (/[a-z0-9]/.test(char)) {​
// If the character is already a key in charCounts, increment its value​
// Otherwise, add it as a new key with value 1​
charCounts[char] = (charCounts[char] || 0) + 1; ​
}​
}​
return charCounts;​
}​
[Link]("Counts for 'hello world':", countChars("hello world")); ​
// Expected: { h: 1, e: 1, l: 3, o: 2, w: 1, r: 1, d: 1 } (excluding space)​
[Link]("Counts for 'Programming is fun':", countChars("Programming is fun")); ​
// Expected: { p: 1, r: 2, o: 2, g: 2, a: 1, m: 2, i: 2, n: 2, s: 1, f: 1, u: 1 } (excluding space)​
[Link]("Counts for 'AAAaaa':", countChars("AAAaaa")); ​
// Expected: { a: 6 }​

Laurence Svekis Learn More [Link]


[Link]("Counts for '123123':", countChars("123123")); ​
// Expected: { '1': 2, '2': 2, '3': 2 }​

Exercise 56: Merge Two Sorted Arrays


// Exercise 56: Merge Two Sorted Arrays​
function mergeSortedArrays(arr1, arr2) {​
const merged = []; ​
let ptr1 = 0; // Pointer for arr1​
let ptr2 = 0; ​
// Pointer for arr2​
// Compare elements from both arrays and add the smaller one to merged​
while (ptr1 < [Link] && ptr2 < [Link]) {​
if (arr1[ptr1] < arr2[ptr2]) {​
[Link](arr1[ptr1]); ​
ptr1++;​
} else {​
[Link](arr2[ptr2]);​
ptr2++; ​
}​
}​
// Add any remaining elements from arr1 (if any)​
while (ptr1 < [Link]) {​
[Link](arr1[ptr1]); ​
ptr1++;​
}​
// Add any remaining elements from arr2 (if any)​
while (ptr2 < [Link]) {​
[Link](arr2[ptr2]); ​
ptr2++;​
}​
return merged;​
}​
[Link]("Merge [1, 3, 5] and [2, 4, 6]:", mergeSortedArrays([1, 3, 5], [2, 4, 6])); ​
// Expected: [1, 2, 3, 4, 5, 6]​
[Link]("Merge [10, 20] and [5, 15, 25]:", mergeSortedArrays([10, 20], [5, 15, 25])); ​
// Expected: [5, 10, 15, 20, 25]​
[Link]("Merge [1, 2] and []:", mergeSortedArrays([1, 2], [])); ​

Laurence Svekis Learn More [Link]


// Expected: [1, 2]​
[Link]("Merge [] and [7, 8]:", mergeSortedArrays([], [7, 8])); ​
// Expected: [7, 8]​

Exercise 57: Find Missing Number in a Sequence


// Exercise 57: Find Missing Number in a Sequence​
function findMissingNumber(arr) {​
const n = [Link] + 1; ​
// If one number is missing, n is (array length + 1)​
// Calculate the expected sum of numbers from 1 to n​
// Formula for sum of an arithmetic series: n * (n + 1) / 2​
const expectedSum = n * (n + 1) / 2; ​
// Calculate the actual sum of numbers in the given array​
let actualSum = 0; ​
for (let i = 0; i < [Link]; i++) {​
actualSum += arr[i]; ​
}​
// Or using reduce: const actualSum = [Link]((sum, num) => sum + num, 0); ​
// The missing number is the difference between the expected and actual sums​
return expectedSum - actualSum; ​
}​
[Link]("Missing number in [1, 2, 4, 5]:", findMissingNumber([1, 2, 4, 5])); ​
// Expected: 3​
[Link]("Missing number in [1, 3]:", findMissingNumber([1, 3])); ​
// Expected: 2 (n=3, sum=6, actual=4)​
[Link]("Missing number in [2, 1, 4, 5, 6, 3, 8]:", findMissingNumber([2, 1, 4, 5, 6, 3,
8])); ​
// Expected: 7 (n=8, sum=36, actual=29)​
[Link]("Missing number in [1]:", findMissingNumber([1])); ​
// Expected: undefined if array is empty (needs error handling)​
[Link]("Missing number in []:", findMissingNumber([])); ​
// Expected: 1 (n=1, sum=1, actual=0)​

Exercise 58: Flatten an Array


// Exercise 58: Flatten an Array​

Laurence Svekis Learn More [Link]


function flattenArray(arr) {​
let flatArr = []; ​
for (let i = 0; i < [Link]; i++) {​
if ([Link](arr[i])) {​
// If the element is an array, recursively flatten it and concatenate​
flatArr = [Link](flattenArray(arr[i])); ​
} else {​
// If it's not an array, just push it​
[Link](arr[i]); ​
}​
}​
return flatArr;​
}​
// Modern ES2019+ built-in method for comparison​
function flattenArrayBuiltIn(arr, depth = 1) {​
return [Link](depth); ​
// flat() can take a depth argument, or Infinity​
}​
const nestedArray1 = [1, [2, 3], 4]; ​
[Link]("Flatten [1, [2, 3], 4]:", flattenArray(nestedArray1)); // Expected: [1, 2, 3, 4] ​
const nestedArray2 = [1, [2, [3, 4]], 5, [6]]; ​
[Link]("Flatten [1, [2, [3, 4]], 5, [6]]:", flattenArray(nestedArray2)); // Expected: [1,
2, 3, 4, 5, 6] ​
const nestedArray3 = [[1, 2], [3, [4, 5]]]; ​
[Link]("Flatten [[1, 2], [3, [4, 5]]]:", flattenArray(nestedArray3)); // Expected: [1, 2,
3, 4, 5] ​
[Link]("\nUsing built-in flat() method:"); ​
[Link]("Flatten [1, [2, 3], 4]:", flattenArrayBuiltIn(nestedArray1));​
[Link]("Flatten [1, [2, [3, 4]], 5, [6]] (depth 1):", flattenArrayBuiltIn(nestedArray2,
1)); ​
[Link]("Flatten [1, [2, [3, 4]], 5, [6]] (depth Infinity):",
flattenArrayBuiltIn(nestedArray2, Infinity)); ​

Exercise 59: Implement a Simple Queue


// Exercise 59: Implement a Simple Queue​
class Queue {​
constructor() {​

Laurence Svekis Learn More [Link]


[Link] = []; ​
// The array to store queue elements​
}​
// Add an element to the back of the queue​
enqueue(element) {​
[Link](element); ​
[Link](`Enqueued: ${element}. Queue: [${[Link](', ')}]`); ​
}​
// Remove and return the element from the front of the queue​
dequeue() {​
if ([Link]()) {​
[Link]("Queue is empty, cannot dequeue."); ​
return undefined;​
}​
const removedElement = [Link](); ​
// Removes from the beginning​
[Link](`Dequeued: ${removedElement}. Queue: [${[Link](', ')}]`);​
return removedElement; ​
}​
// Return the element at the front of the queue without removing it​
peek() {​
if ([Link]()) {​
[Link]("Queue is empty, nothing to peek."); ​
return undefined;​
}​
const frontElement = [Link][0];​
[Link](`Peeked: ${frontElement}.`);​
return frontElement; ​
}​
// Check if the queue is empty​
isEmpty() {​
return [Link] === 0; ​
}​
// Get the number of elements in the queue​
size() {​
return [Link]; ​
}​
// For debugging/display​
printQueue() {​

Laurence Svekis Learn More [Link]


[Link](`Current Queue: [${[Link](', ')}] (Size: ${[Link]()})`); ​
}​
}​
// Demonstrate Queue usage​
const myQueue = new Queue();​
[Link]("Is queue empty?", [Link]()); // Expected: true ​
[Link]("Task 1"); ​
[Link]("Task 2");​
[Link]("Task 3");​
[Link]();​
[Link]("Queue size:", [Link]()); // Expected: 3​
[Link](); // Expected: Peeked: Task 1. ​
[Link](); ​
// Expected: Dequeued: Task 1. Queue: [Task 2, Task 3]​
[Link](); // Expected: Peeked: Task 2. ​
[Link](); ​
// Expected: Dequeued: Task 2. Queue: [Task 3]​
[Link](); // Expected: Dequeued: Task 3. Queue: [] ​
[Link](); ​
// Expected: Queue is empty, cannot dequeue.​
[Link]("Is queue empty?", [Link]()); ​
// Expected: true​

Exercise 60: Implement a Simple Stack


// Exercise 60: Implement a Simple Stack​
class Stack {​
constructor() {​
[Link] = []; ​
// The array to store stack elements​
}​
// Add an element to the top of the stack​
push(element) {​
[Link](element); ​
[Link](`Pushed: ${element}. Stack: [${[Link](', ')}]`); ​
}​
// Remove and return the element from the top of the stack​
pop() {​

Laurence Svekis Learn More [Link]


if ([Link]()) {​
[Link]("Stack is empty, cannot pop."); ​
return undefined;​
}​
const poppedElement = [Link](); ​
// Removes from the end​
[Link](`Popped: ${poppedElement}. Stack: [${[Link](', ')}]`);​
return poppedElement; ​
}​
// Return the element at the top of the stack without removing it​
peek() {​
if ([Link]()) {​
[Link]("Stack is empty, nothing to peek."); ​
return undefined;​
}​
const topElement = [Link][[Link] - 1];​
[Link](`Peeked: ${topElement}.`);​
return topElement; ​
}​
// Check if the stack is empty​
isEmpty() {​
return [Link] === 0; ​
}​
// Get the number of elements in the stack​
size() {​
return [Link]; ​
}​
// For debugging/display​
printStack() {​
[Link](`Current Stack: [${[Link](', ')}] (Size: ${[Link]()})`); ​
}​
}​
// Demonstrate Stack usage​
const myStack = new Stack();​
[Link]("Is stack empty?", [Link]()); // Expected: true ​
[Link]("Page 1"); ​
[Link]("Page 2");​
[Link]("Page 3");​
[Link]();​

Laurence Svekis Learn More [Link]


[Link]("Stack size:", [Link]()); // Expected: 3​
[Link](); // Expected: Peeked: Page 3. ​
[Link](); ​
// Expected: Popped: Page 3. Stack: [Page 1, Page 2]​
[Link](); // Expected: Peeked: Page 2. ​
[Link](); ​
// Expected: Popped: Page 2. Stack: [Page 1]​
[Link](); // Expected: Popped: Page 1. Stack: [] ​
[Link](); ​
// Expected: Stack is empty, cannot pop.​
[Link]("Is stack empty?", [Link]()); ​
// Expected: true​

Exercise 61: [Link]()


// Exercise 61: [Link]()​
function fetchData(name, delay) {​
return new Promise(resolve => {​
setTimeout(() => {​
[Link](`Finished fetching ${name} after ${delay}ms`);​
resolve(`Data from ${name}`);​
}, delay);​
}); ​
}​
[Link]("Starting all data fetches...");​
// Create an array of Promises​
const allPromises = [​
fetchData("Service A", 2000), // Longest delay​
fetchData("Service B", 1000),​
fetchData("Service C", 1500)​
]; ​
// Use [Link] to wait for all promises to resolve​
[Link](allPromises)​
.then(results => {​
[Link]("\nAll data received:");​
[Link](results); // Expected: ["Data from Service A", "Data from Service B",
"Data from Service C"]​
})​

Laurence Svekis Learn More [Link]


.catch(error => {​
[Link]("One of the fetches failed:", error);​
}); ​
[Link]("Meanwhile, other tasks can run in the main thread."); ​

Exercise 62: Basic Event Loop Understanding with


setTimeout
// Exercise 62: Basic Event Loop Understanding with setTimeout​
[Link]("1. Start of script."); ​
setTimeout(() => {​
[Link]("3. Inside setTimeout callback (0ms delay).");​
}, 0); ​
// Scheduled to run as soon as possible after call stack is clear​
setTimeout(() => {​
[Link]("4. Inside setTimeout callback (100ms delay).");​
}, 100); ​
// Scheduled to run after at least 100ms​
[Link]("2. End of script."); ​
// This loop simulates a long-running synchronous task​
// It will block the main thread and prevent the 0ms timeout from executing
immediately​
// even though its delay is 0ms.​
let sum = 0; ​
for (let i = 0; i < 1000000000; i++) {​
sum += i; ​
}​
[Link]("5. Long synchronous task finished. Sum:", sum); // This will appear before
any timeouts ​

Exercise 63: Error Handling in async/await with


try...catch
// Exercise 63: Error Handling in async/await with try...catch​
// Reusing the Promise-based function from Exercise 27/41​
function fetchUserDataPromise(userId) {​
return new Promise((resolve, reject) => {​

Laurence Svekis Learn More [Link]


setTimeout(() => {​
if (userId === 0 || userId < 0) { // Simulate error for 0 or negative IDs​
reject(`Error: User with ID ${userId} not found or invalid.`);​
return;​
}​
const user = {​
id: userId,​
name: `User ${userId}`,​
status: "active"​
};​
resolve(user);​
}, 800); // Shorter delay for demonstration​
}); ​
}​
async function processUserData(userId) {​
[Link](`\nAttempting to process data for user ID: ${userId}...`); ​
try {​
const user = await fetchUserDataPromise(userId); ​
// Await the promise​
[Link](`Success! Data for user ${userId}:`, user); ​
} catch (error) {​
// If fetchUserDataPromise rejects, the error is caught here​
[Link](`Failed to process data for user ID ${userId}:`, error); ​
} finally {​
[Link](`Finished processing attempt for user ID: ${userId}.`); ​
}​
}​
// Demonstrate usage:​
processUserData(10); ​
// Success case​
processUserData(0); // Error case ​
processUserData(15); // Another success case ​
processUserData(-1); ​
// Another error case​

Exercise 64: Generators (Basic)


// Exercise 64: Generators (Basic)​

Laurence Svekis Learn More [Link]


function* idGenerator() {​
let id = 1; ​
while (true) { // This loop will run indefinitely until the generator is stopped​
yield id++; ​
// Pause execution and return the current 'id', then increment it for the next call​
}​
}​
// Create a generator object​
const myIdGenerator = idGenerator(); ​
[Link]("Generated IDs:");​
[Link]([Link]().value); // Expected: 1 ​
[Link]([Link]().value); // Expected: 2 ​
[Link]([Link]().value); ​
// Expected: 3​
// You can create another independent generator​
const anotherIdGenerator = idGenerator();​
[Link]([Link]().value); ​
// Expected: 1 (starts fresh)​
[Link]([Link]().value); // Expected: 4 (myIdGenerator continues) ​

Exercise 65: Iterators (Basic Custom)


// Exercise 65: Iterators (Basic Custom)​
class MyRange {​
constructor(from, to) {​
[Link] = from; ​
[Link] = to;​
}​
// This method makes the object "iterable"​
[[Link]]() {​
let current = [Link]; ​
// Keep track of the current number​
// The iterator object must have a 'next' method​
return {​
next: () => {​
if (current <= [Link]) {​
// If there are more numbers, return the current one and advance​
return { done: false, value: current++ }; ​

Laurence Svekis Learn More [Link]


} else {​
// If the range is exhausted, signal completion​
return { done: true }; ​
}​
}​
}; ​
}​
}​
[Link]("Numbers in range 1 to 5:");​
for (let num of new MyRange(1, 5)) {​
[Link](num); ​
// Expected: 1, 2, 3, 4, 5​
}​
[Link]("\nNumbers in range 7 to 10:"); ​
for (let num of new MyRange(7, 10)) {​
[Link](num); ​
// Expected: 7, 8, 9, 10​
}​

Exercise 66: JavaScript Modules (Basic import/export)


// Exercise 66: JavaScript Modules (Basic import/export)​
// --- content of [Link] ---​
// export function capitalize(str) {​
// if (!str) return '';​
// return [Link](0).toUpperCase() + [Link](1).toLowerCase();​
// }​
// export const APP_NAME = "My Awesome App";​
// export const PI_VALUE = 3.14159;​
//​
// Default export (only one per module)​
// export default class Greeter {​
// constructor(name) {​
// [Link] = name;​
// }​
// sayHello() {​
// [Link](`Hello, ${[Link]}!`);​
// }​

Laurence Svekis Learn More [Link]


// }​
// --- content of [Link] ---​
// import { capitalize, APP_NAME, PI_VALUE } from './[Link]';​
// Named imports​
// import MyGreeter from './[Link]'; // Default import (any name)​
// [Link](`Application Name: ${APP_NAME}`);​
// [Link](`Capitalized "hello": ${capitalize("hello")}`);​
// [Link](`Value of PI: ${PI_VALUE}`);​
// const greeterInstance = new MyGreeter("Module User");​
// [Link]();​
[Link]("This exercise describes modules conceptually.");​
[Link]("See the commented-out code for example `[Link]` and `[Link]` file
structures."); ​
[Link]("\nTo run this in a browser, you'd use a script tag like:");​
[Link]('<script type="module" src="[Link]"></script>'); ​
[Link]("\nEach module runs in strict mode and has its own top-level scope."); ​

Exercise 67: Simple Event Emitter (Custom


Implementation)
// Exercise 67: Simple Event Emitter (Custom Implementation)​
class EventEmitter {​
constructor() {​
[Link] = new Map(); ​
// Stores event names as keys and arrays of listener functions as values​
}​
// Register a listener for a specific event​
on(eventName, listener) {​
if (![Link](eventName)) {​
[Link](eventName, []); ​
// If event doesn't exist, create an empty array for its listeners​
}​
[Link](eventName).push(listener); ​
// Add the listener to the array​
[Link](`Registered listener for '${eventName}'.`); ​
}​
// Emit an event, calling all registered listeners​
emit(eventName, ...args) { // ...args allows passing any number of arguments to

Laurence Svekis Learn More [Link]


listeners​
const eventListeners = [Link](eventName); ​
if (eventListeners) {​
[Link](`Emitting event '${eventName}' with args: ${[Link](args)}`); ​
[Link](listener => {​
try {​
listener(...args); // Call each listener with the provided arguments​
} catch (e) {​
[Link](`Error in listener for '${eventName}':`, e);​
}​
}); ​
} else {​
[Link](`No listeners registered for '${eventName}'.`); ​
}​
}​
// Remove a specific listener for an event​
off(eventName, listenerToRemove) {​
const eventListeners = [Link](eventName); ​
if (eventListeners) {​
const index = [Link](listenerToRemove); ​
if (index > -1) {​
[Link](index, 1); ​
// Remove the listener from the array​
[Link](`Unregistered listener for '${eventName}'.`); ​
} else {​
[Link](`Listener not found for '${eventName}'.`); ​
}​
} else {​
[Link](`No listeners registered for '${eventName}'.`); ​
}​
}​
}​
// Demonstrate usage​
const myEmitter = new EventEmitter(); ​
// Define some listener functions​
const greetListener = (name) => [Link](`Hello, ${name}!`);​

🎉
const logDataListener = (data) => [Link](`Received data: ${data}`); ​
const celebrateListener = (count, message) => [Link](` Celebrating ${count}
times: ${message}`); // Register listeners ​

Laurence Svekis Learn More [Link]


[Link]("greet", greetListener);​
[Link]("dataLoaded", logDataListener);​
[Link]("celebrate", celebrateListener); ​
[Link]("greet", (name) => [Link](`A secondary greeting to ${name}.`)); //
Multiple listeners for same event​
// Emit events​
[Link]("greet", "Alice"); ​
[Link]("dataLoaded", { id: 101, status: "completed" });​
[Link]("celebrate", 3, "New Milestone!");​
[Link]("unknownEvent", "This won't do anything."); ​
// No listeners for this​
// Unregister a listener​
[Link]("greet", greetListener);​
[Link]("greet", "Bob"); ​
// greetListener won't be called now​
[Link]("greet", greetListener); // Trying to remove again (should log "Listener
not found") ​

Exercise 68: WeakSet Data Structure


// Exercise 68: WeakSet Data Structure​
// WeakSet can only store objects (not primitive values)​
const weakSet = new WeakSet(); ​
let user1 = { id: 1, name: "Alice" };​
let user2 = { id: 2, name: "Bob" }; ​
let user3 = { id: 3, name: "Charlie" }; // Add objects to the WeakSet ​
[Link](user1);​
[Link](user2);​
[Link](user3); ​
[Link]("WeakSet after adding objects.");​
[Link]("WeakSet has user1:", [Link](user1)); // Expected: true ​
[Link]("WeakSet has user2:", [Link](user2)); ​
// Expected: true​
[Link]("WeakSet has user4 (non-existent):", [Link]({ id: 4 })); ​
// Expected: false (new object)​
// Delete an object from WeakSet​
[Link](user2);​
[Link]("WeakSet has user2 after deletion:", [Link](user2)); ​

Laurence Svekis Learn More [Link]


// Expected: false​
// What happens if an object is no longer referenced elsewhere? ​
// Let's remove the strong reference to user3​
user3 = null; ​
// user3 is now eligible for garbage collection​
// The WeakSet will automatically remove user3 if it's garbage collected. ​
// However, we cannot directly observe this or iterate the WeakSet to prove it. ​
// The `has` method might still return true for a short while if GC hasn't run. ​
// There is no .size property or iteration methods on WeakSet. ​
// A common use case: keeping track of objects that have certain permissions or
states,​
// without preventing them from being garbage collected if they are no longer used
elsewhere. ​
class Permissions {​
constructor() {​
[Link] = new WeakSet(); ​
}​
grantAdmin(userObj) {​
[Link](userObj); ​
}​
isAdmin(userObj) {​
return [Link](userObj);​
}​
}​
const permSystem = new Permissions(); ​
let currentUser = { id: 10, name: "AdminUser" };​
[Link](currentUser);​
[Link]("Is currentUser an admin?", [Link](currentUser)); ​
// Expected: true​
currentUser = null; // AdminUser object becomes eligible for GC​
// At some point later, it will be automatically removed from [Link]​
// without us having to explicitly delete it. ​

Exercise 69: WeakMap Data Structure


// Exercise 69: WeakMap Data Structure​
// WeakMap can only use objects as keys (not primitive values)​
const weakMap = new WeakMap(); ​

Laurence Svekis Learn More [Link]


let obj1 = { name: "Config A" };​
let obj2 = { name: "User Session" }; ​
let obj3 = { name: "DOM Element Ref" }; // Set key-value pairs ​
[Link](obj1, { version: 1.0, active: true }); ​
[Link](obj2, { sessionId: "xyz123", lastAccess: new Date() });​
[Link](obj3, "This is data for the DOM element");​
[Link]("WeakMap after setting entries."); ​
[Link]("Data for obj1:", [Link](obj1)); // Expected: { version: 1, active: true } ​
[Link]("WeakMap has obj2:", [Link](obj2)); ​
// Expected: true​
[Link]("Data for obj3:", [Link](obj3)); // Expected: This is data for the
DOM element ​
// Delete an entry​
[Link](obj1); ​
[Link]("Data for obj1 after deletion:", [Link](obj1)); // Expected: undefined ​
// What happens if a key object is no longer referenced elsewhere? ​
obj2 = null; // obj2 (the key) is now eligible for garbage collection ​
// If obj2 is garbage collected, its entry in weakMap will also be automatically removed. ​
// Like WeakSet, WeakMap has no .size property and cannot be iterated. ​
// We cannot directly observe the entry's removal until GC runs. ​
// A common use case: associating private data with objects​
const privateData = new WeakMap(); ​
class User {​
constructor(name, initialPrivateInfo) {​
[Link] = name;​
[Link](this, initialPrivateInfo); ​
// Store private data in WeakMap using 'this' as key​
}​
getPrivateInfo() {​
return [Link](this); ​
}​
updatePrivateInfo(newInfo) {​
[Link](this, newInfo); ​
}​
}​
let user = new User("Jane Doe", { secretId: "abc", role: "admin" });​
[Link]("User private info:", [Link]()); ​
[Link]({ secretId: "def", role: "guest" });​
[Link]("User updated private info:", [Link]());​

Laurence Svekis Learn More [Link]


user = null; ​
// User object is now eligible for GC, and its associated private data in WeakMap will
also be removed. ​

Exercise 70: Set for Counting Unique Elements


(Advanced)
// Exercise 70: Set for Counting Unique Elements (Advanced)​
function countUniqueElements(arr) {​
const uniqueItems = new Set(arr); ​
// Create a Set from the array, automatically handling uniqueness​
return [Link]; ​
// The size property of the Set gives the count of unique elements​
}​
[Link]("Unique count in [1, 2, 2, 3, 4, 4, 5]:", countUniqueElements([1, 2, 2, 3, 4, 4,
5])); ​
// Expected: 5​
[Link]("Unique count in ['apple', 'banana', 'apple', 'orange']:",
countUniqueElements(['apple', 'banana', 'apple', 'orange'])); ​
// Expected: 3​
[Link]("Unique count in []:", countUniqueElements([])); // Expected: 0 ​
[Link]("Unique count in [1, 1, 1, 1]:", countUniqueElements([1, 1, 1, 1])); ​
// Expected: 1​
[Link]("Unique count in [1, '1', 2]:", countUniqueElements([1, '1', 2])); ​
// Expected: 3 (Set distinguishes number 1 from string '1')​

Exercise 71: Selecting Elements by ID


<!DOCTYPE html>​
<html lang="en">​
<head>​
<meta charset="UTF-8">​
<meta name="viewport" content="width=device-width, initial-scale=1.0">​
<title>Exercise 71</title>​
</head>​
<body>​
<p id="myParagraph">This is the original paragraph text.</p>​

Laurence Svekis Learn More [Link]



<script>​
[Link]('DOMContentLoaded', () => {​
// 1. Select the paragraph element by its ID​
const paragraph = [Link]('myParagraph'); ​
// 2. Check if the element exists before trying to modify it​
if (paragraph) {​
// 3. Change its text content​
[Link] = "Hello from JavaScript! The ID selector worked."; ​
[Link]("Paragraph text changed successfully!");​
} else {​
[Link]("Element with ID 'myParagraph' not found!");​
}​
});​
[Link]("Run this code in an HTML file to see the DOM manipulation."); ​
</script>​
</body>​
</html>​

Exercise 72: Selecting Elements by Class Name


<!DOCTYPE html>​
<html lang="en">​
<head>​
<meta charset="UTF-8">​
<meta name="viewport" content="width=device-width, initial-scale=1.0">​
<title>Exercise 72</title>​
</head>​
<body>​
<ul>​
<li class="listItem">First Original Item</li>​
<li class="listItem">Second Original Item</li>​
<li class="listItem">Third Original Item</li>​
</ul>​

<script>​
[Link]('DOMContentLoaded', () => {​
// 1. Select all elements with the class 'listItem'​

Laurence Svekis Learn More [Link]


const listItems = [Link]('listItem'); ​
[Link](`Found ${[Link]} elements with class 'listItem'.`);​
// 2. Iterate through the HTMLCollection (which is array-like, not a true array)​
for (let i = 0; i < [Link]; i++) {​
listItems[i].textContent = `Item ${i + 1} - Updated by JS`; ​
}​
// Alternative for iteration (converting to Array):​
// [Link](listItems).forEach((item, index) => {​
// [Link] = `Item ${index + 1} - Updated by JS (using forEach)`;​
// });​
[Link]("List item texts changed successfully!");​
});​
[Link]("Run this code in an HTML file to see the DOM manipulation."); ​
</script>​
</body>​
</html>​

Exercise 73: Selecting Elements with querySelector


and querySelectorAll
<!DOCTYPE html>​
<html lang="en">​
<head>​
<meta charset="UTF-8">​
<meta name="viewport" content="width=device-width, initial-scale=1.0">​
<title>Exercise 73</title>​
<style>​
#container {​
border: 1px solid #ccc;​
padding: 15px;​
margin: 20px;​
border-radius: 8px;​
background-color: #f9f9f9;​
}​
p {​
margin-bottom: 10px;​
}​
</style>​

Laurence Svekis Learn More [Link]


</head>​
<body>​
<div id="container">​
<h3>Container Content</h3>​
<p class="intro">This is the introductory paragraph within the container.</p>​
<p>First general paragraph.</p>​
<p>Second general paragraph.</p>​
<span class="intro">This span also has intro class, but shouldn't be selected by
'[Link]'</span>​
</div>​

<script>​
[Link]('DOMContentLoaded', () => {​
// 1. Select the first element that matches the CSS selector​
const introParagraph = [Link]('#container .intro'); ​
if (introParagraph) {​
[Link] = "The intro paragraph has been updated!"; ​
[Link] = "blue"; ​
[Link]("Intro paragraph updated using querySelector.");​
} else {​
[Link]("Intro paragraph not found!");​
}​
// 2. Select all elements that match the CSS selector​
const allParagraphs = [Link]('#container p'); ​
[Link](`Found ${[Link]} paragraphs inside container.`);​
// 3. Iterate through the NodeList (which behaves like an Array for iteration)​
[Link]((p, index) => {​
[Link] = (index % 2 === 0) ? '#e0ffe0' : '#f0fff0'; //
Alternate background ​
[Link] = '5px';​
[Link] = '5px';​
[Link] = '5px'; ​
[Link] = '1px solid #ccc';​
});​
[Link]("All paragraphs inside container styled using querySelectorAll.");​
});​
[Link]("Run this code in an HTML file to see the DOM manipulation."); ​
</script>​
</body>​

Laurence Svekis Learn More [Link]


</html>​

Exercise 74: Modifying Element Attributes


<!DOCTYPE html>​
<html lang="en">​
<head>​
<meta charset="UTF-8">​
<meta name="viewport" content="width=device-width, initial-scale=1.0">​
<title>Exercise 74</title>​
</head>​
<body>​
<img id="myImage"
src="[Link] alt="An original
placeholder image."​
style="border: 2px solid grey; margin: 10px;">​

<script>​
[Link]('DOMContentLoaded', () => {​
const myImage = [Link]('myImage');​
if (myImage) {​
[Link]("Original Image Src:", [Link]('src'));​
[Link]("Original Image Alt:", [Link]('alt'));​
// 1. Change its src attribute​
[Link]('src',
'[Link] ​
[Link]("Image src changed.");​
// 2. Change its alt attribute​
[Link]('alt', 'A descriptive new image for the placeholder.'); ​
[Link]("Image alt changed.");​
// 3. Add a title attribute​
[Link]('title', 'Hover to see title! Click me!'); ​
[Link]("Image title added.");​
// 4. Remove the alt attribute after 2 seconds​
setTimeout(() => {​
[Link]('alt'); ​
[Link]("Image alt attribute removed after 2 seconds.");​
[Link]("Current Image Alt (after removal):",

Laurence Svekis Learn More [Link]


[Link]('alt')); ​
// Will be null​
}, 2000);​
} else {​
[Link]("Element with ID 'myImage' not found!");​
}​
});​
[Link]("Run this code in an HTML file to see the DOM manipulation."); ​
</script>​
</body>​
</html>​

Exercise 75: Adding and Removing CSS Classes


<!DOCTYPE html>​
<html lang="en">​
<head>​
<meta charset="UTF-8">​
<meta name="viewport" content="width=device-width, initial-scale=1.0">​
<title>Exercise 75</title>​
<style>​
#myBox {​
width: 150px;​
height: 150px;​
background-color: lightgrey; ​
margin: 20px;​
display: flex;​
justify-content: center;​
align-items: center;​
font-size: 1.2em;​
transition: background-color 0.3s ease, border 0.3s ease; ​
border: 2px solid transparent;​
border-radius: 8px;​
}​
.highlight {​
background-color: #ffd700; /* Gold */ ​
border-color: #da0037; /* Dark Red */​
box-shadow: 0 0 10px rgba(255, 215, 0, 0.5); ​

Laurence Svekis Learn More [Link]


}​
/* Basic styling for buttons (optional, can use Tailwind/Bootstrap) */​
button {​
padding: 8px 15px;​
margin: 5px;​
border: none;​
border-radius: 5px;​
cursor: pointer;​
color: white;​
font-weight: bold;​
}​
#addHighlightBtn { background-color: #4CAF50; } /* Green */​
#removeHighlightBtn { background-color: #f44336; } /* Red */​
#toggleHighlightBtn { background-color: #008CBA; } /* Blue */​
</style>​
</head>​
<body>​
<button id="addHighlightBtn">Add Highlight</button>​
<button id="removeHighlightBtn">Remove Highlight</button>​
<button id="toggleHighlightBtn">Toggle Highlight</button>​
<div id="myBox">Interactive Box</div>​

<script>​
[Link]('DOMContentLoaded', () => {​
const myBox = [Link]('myBox');​
const addBtn = [Link]('addHighlightBtn');​
const removeBtn = [Link]('removeHighlightBtn');​
const toggleBtn = [Link]('toggleHighlightBtn');​

if (myBox && addBtn && removeBtn && toggleBtn) {​
[Link]('click', () => {​
[Link]('highlight'); ​
[Link]("Class 'highlight' added.");​
});​
[Link]('click', () => {​
[Link]('highlight'); ​
[Link]("Class 'highlight' removed.");​
});​
[Link]('click', () => {​

Laurence Svekis Learn More [Link]


[Link]('highlight'); ​
[Link]("Class 'highlight' toggled.");​
});​
} else {​
[Link]("One or more elements not found!");​
}​
});​
[Link]("Run this code in an HTML file to see the DOM manipulation."); ​
</script>​
</body>​
</html>​

Exercise 76: Creating and Appending Elements


<!DOCTYPE html>​
<html lang="en">​
<head>​
<meta charset="UTF-8">​
<meta name="viewport" content="width=device-width, initial-scale=1.0">​
<title>Exercise 76</title>​
<style>​
#outputContainer {​
border: 1px dashed grey;​
padding: 10px;​
margin-top: 20px;​
border-radius: 5px;​
background-color: #f8f8f8;​
}​
</style>​
</head>​
<body>​
<div id="outputContainer">​
<h3>Content will be added below:</h3>​
</div>​

<script>​
[Link]('DOMContentLoaded', () => {​
const outputContainer = [Link]('outputContainer');​

Laurence Svekis Learn More [Link]


if (outputContainer) {​
// 1. Create a new <h2> element​
const newHeading = [Link]('h2'); ​
[Link] = "Dynamically Created Heading"; ​
[Link] = "#2c3e50";​
[Link] = "10px";​
// 2. Create a new paragraph element​
const newParagraph = [Link]('p'); ​
[Link] = "This paragraph was proudly added by
JavaScript!"; ​
[Link] = "italic";​
[Link] = "#34495e";​
[Link] = "10px";​
// 3. Append both new elements to the outputContainer​
[Link](newHeading); ​
[Link](newParagraph); ​
[Link]("New elements created and appended to outputContainer.");​

// Create and append a button that adds more content​
const addButton = [Link]('button'); ​
[Link] = "Add More Content";​
[Link] = "bg-purple-600 text-white p-2 rounded-md mt-4";
/* Example class, for visual */​
[Link](addButton);​

let clickCount = 0; ​
[Link]('click', () => {​
clickCount++;​
const dynamicPara = [Link]('p');​
[Link] = `You clicked the button! This is dynamic
content #${clickCount}.`;​
[Link] = '#f0f4f8';​
[Link] = '5px';​
[Link] = '4px';​
[Link] = '5px';​
[Link](dynamicPara, addButton); // Insert before
the button ​
});​
} else {​

Laurence Svekis Learn More [Link]


[Link]("Element with ID 'outputContainer' not found!");​
}​
});​
[Link]("Run this code in an HTML file to see the DOM manipulation."); ​
</script>​
</body>​
</html>​

Exercise 77: Basic Event Listener (click)


<!DOCTYPE html>​
<html lang="en">​
<head>​
<meta charset="UTF-8">​
<meta name="viewport" content="width=device-width, initial-scale=1.0">​
<title>Exercise 77</title>​
</head>​
<body>​
<button id="myButton">Click Me</button>​
<p id="clickCountDisplay" style="margin-top: 10px; font-size: 1.2em;">Clicks: 0</p>​

<script>​
[Link]('DOMContentLoaded', () => {​
const myButton = [Link]('myButton');​
const clickCountDisplay = [Link]('clickCountDisplay');​
let clickCount = 0;​

if (myButton && clickCountDisplay) {​
// Add a click event listener to the button​
[Link]('click', () => {​
clickCount++;​
[Link]("Button clicked! Total clicks:", clickCount); ​
[Link] = `Clicks: ${clickCount}`; ​
// Add a temporary visual feedback​
[Link] = 'scale(0.98)';​
setTimeout(() => {​
[Link] = 'scale(1)';​
}, 100);​

Laurence Svekis Learn More [Link]


});​
} else {​
[Link]("Button or display element not found!");​
}​
});​
[Link]("Run this code in an HTML file and click the button to see console
output."); ​
</script>​
</body>​
</html>​

Exercise 78: Input Event Listener (input)


<!DOCTYPE html>​
<html lang="en">​
<head>​
<meta charset="UTF-8">​
<meta name="viewport" content="width=device-width, initial-scale=1.0">​
<title>Exercise 78</title>​
<style>​
input[type="text"] {​
padding: 8px;​
width: 250px;​
border: 1px solid #ccc;​
border-radius: 4px;​
margin-bottom: 10px;​
}​
#displayArea {​
font-size: 1.1em;​
color: #333;​
}​
</style>​
</head>​
<body>​
<div>​
<label for="myInput">Type something:</label><br>​
<input type="text" id="myInput">​
<p id="displayArea">You typed: <span style="font-weight: bold; color:

Laurence Svekis Learn More [Link]


blue;"></span></p>​
</div>​

<script>​
[Link]('DOMContentLoaded', () => {​
const myInput = [Link]('myInput');​
const displayArea = [Link]('displayArea');​
const typedTextSpan = displayArea ? [Link]('span') : null; //
Span to update​

if (myInput && displayArea && typedTextSpan) {​
// Add an 'input' event listener to the input field​
[Link]('input', (event) => {​
// [Link] refers to the element that triggered the event (the input
field)​
// [Link] gives the current value of the input field​
[Link] = [Link]; ​
[Link]("Input value:", [Link]);​
});​
} else {​
[Link]("Input or display elements not found!");​
}​
});​
[Link]("Run this code in an HTML file and type into the input field to see live
updates."); ​
</script>​
</body>​
</html>​

Exercise 79: fetch API (Simple GET Request)


<!DOCTYPE html>​
<html lang="en">​
<head>​
<meta charset="UTF-8">​
<meta name="viewport" content="width=device-width, initial-scale=1.0">​
<title>Exercise 79</title>​
</head>​

Laurence Svekis Learn More [Link]


<body>​
<h1>Fetch API Example</h1>​
<p>Check the browser's console for the fetched data.</p>​

<script>​
// A public API endpoint to fetch data from​
const API_URL = '[Link]
const INVALID_API_URL = '[Link]
// To demonstrate error​

async function fetchAndDisplayPost(url) {​
[Link](`\nAttempting to fetch data from: ${url}`); ​
try {​
const response = await fetch(url); ​
// Initiate the fetch request​

// Check if the request was successful (status code 200-299)​
if (![Link]) {​
// If not successful, throw an error with the status text​
throw new Error(`HTTP error! Status: ${[Link]} -
${[Link]}`); ​
}​

const data = await [Link](); ​
// Parse the response body as JSON​
[Link]("Successfully fetched data:");​
[Link](data); ​
// Log the parsed JSON data​

} catch (error) {​
// Catch any network errors or errors thrown from the [Link] check​
[Link]("Error fetching data:", [Link]); ​
}​
}​

// Call the function to fetch data​
fetchAndDisplayPost(API_URL);​
fetchAndDisplayPost(INVALID_API_URL); ​
// To demonstrate error handling​

Laurence Svekis Learn More [Link]



[Link]("This message will appear before the fetch results, demonstrating
asynchronicity."); ​
</script>​
</body>​
</html>​

Exercise 80: Basic Animation with setInterval


<!DOCTYPE html>​
<html lang="en">​
<head>​
<meta charset="UTF-8">​
<meta name="viewport" content="width=device-width, initial-scale=1.0">​
<title>Exercise 80</title>​
<style>​
#animatedBox {​
width: 60px;​
height: 60px;​
background-color: #28a745; /* Green */ ​
border-radius: 8px;​
position: relative; /* Essential for 'left' property to work */ ​
left: 0px;​
top: 10px;​
transition: background-color 0.3s ease; ​
}​
.controls {​
margin-top: 20px; ​
}​
.control-btn {​
padding: 8px 16px;​
border-radius: 6px;​
font-size: 1em;​
cursor: pointer;​
border: none; ​
margin-right: 10px;​
transition: background-color 0.2s ease;​
}​

Laurence Svekis Learn More [Link]


.start-btn { background-color: #007bff; color: white; } ​
.start-btn:hover { background-color: #0056b3; }​
.stop-btn { background-color: #dc3545; color: white; } ​
.stop-btn:hover { background-color: #b02a3a; }​
</style>​
</head>​
<body>​
<div id="animatedBox"></div>​
<div class="controls">​
<button id="startButton" class="control-btn start-btn">Start Animation</button>​
<button id="stopButton" class="control-btn stop-btn">Stop Animation</button>​
</div>​

<script>​
[Link]('DOMContentLoaded', () => {​
const animatedBox = [Link]('animatedBox');​
const startButton = [Link]('startButton');​
const stopButton = [Link]('stopButton');​

let position = 0;​
let animationIntervalId;​
const speed = 2; // Pixels per interval​
const maxPosition = [Link] - 80; // Stop before going off screen
(adjust for box width)​
const intervalDelay = 10; // Milliseconds per update​

function animateBox() {​
if (animatedBox) {​
animationIntervalId = setInterval(() => {​
position += speed;​
if (position > maxPosition) {​
position = 0; // Reset to start​
}​
[Link] = position + 'px'; ​
}, intervalDelay);​
[Link]("Animation started.");​
} else {​
[Link]("Animated box not found!"); ​
}​

Laurence Svekis Learn More [Link]


}​

function stopAnimation() {​
if (animationIntervalId) {​
clearInterval(animationIntervalId); ​
animationIntervalId = null;​
[Link]("Animation stopped.");​
}​
}​

if (startButton && stopButton) {​
[Link]('click', () => {​
if (!animationIntervalId) { // Prevent starting multiple intervals​
animateBox();​
}​
});​
[Link]('click', stopAnimation);​
// Optional: Stop animation if window resizes to recalculate maxPosition​
[Link]('resize', stopAnimation); ​
} else {​
[Link]("Animation control buttons not found!");​
}​
});​
[Link]("Run this code in an HTML file to see the animation."); ​
</script>​
</body>​
</html>​

Exercise 81: Binary Search


// Exercise 81: Binary Search​
function binarySearch(arr, target) {​
let left = 0; ​
let right = [Link] - 1;​
while (left <= right) {​
const mid = [Link]((left + right) / 2); ​
// Calculate the middle index​
// Check if the middle element is the target​

Laurence Svekis Learn More [Link]


if (arr[mid] === target) {​
return mid; ​
// Target found​
}​
// If the target is greater, ignore the left half​
if (arr[mid] < target) {​
left = mid + 1; ​
}​
// If the target is smaller, ignore the right half​
else {​
right = mid - 1; ​
}​
}​
return -1; // Target not found in the array​
}​
const sortedArray = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]; ​
[Link]("Index of 12:", binarySearch(sortedArray, 12)); // Expected: 3 ​
[Link]("Index of 23:", binarySearch(sortedArray, 23)); ​
// Expected: 5​
[Link]("Index of 2:", binarySearch(sortedArray, 2)); // Expected: 0 ​
[Link]("Index of 91:", binarySearch(sortedArray, 91)); ​
// Expected: 9​
[Link]("Index of 7:", binarySearch(sortedArray, 7)); // Expected: -1 (not found) ​
[Link]("Index of 100:", binarySearch(sortedArray, 100)); ​
// Expected: -1 (not found)​
[Link]("Index of 38:", binarySearch(sortedArray, 38)); ​
// Expected: 6​

Exercise 82: Bubble Sort


// Exercise 82: Bubble Sort​
function bubbleSort(arr) {​
const n = [Link]; ​
let swapped; // Flag to optimize: if no swaps in an pass, array is sorted​
// Outer loop: iterate through the array from the beginning​
// After each pass, the largest unsorted element "bubbles" to its correct position at
the end​
for (let i = 0; i < n - 1; i++) {​

Laurence Svekis Learn More [Link]


swapped = false; ​
// Reset flag for each pass​
// Inner loop: compare adjacent elements and swap if they are in the wrong order​
// The last 'i' elements are already in place, so we don't need to check them​
for (let j = 0; j < n - 1 - i; j++) {​
if (arr[j] > arr[j + 1]) {​
// Swap arr[j] and arr[j + 1]​
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // ES6 array destructuring for swapping ​
swapped = true; ​
// A swap occurred in this pass​
}​
}​
// Optimization: If no two elements were swapped by inner loop, then array is sorted​
if (!swapped) {​
break; ​
}​
}​
return arr; // Return the sorted array​
}​
const unsortedArray1 = [64, 34, 25, 12, 22, 11, 90]; ​
[Link]("Bubble Sort [64, 34, 25, 12, 22, 11, 90]:", bubbleSort([...unsortedArray1])); ​
// Use spread to avoid mutating original​
const unsortedArray2 = [5, 1, 4, 2, 8]; ​
[Link]("Bubble Sort [5, 1, 4, 2, 8]:", bubbleSort([...unsortedArray2]));​
const unsortedArray3 = [1, 2, 3, 4, 5]; ​
// Already sorted​
[Link]("Bubble Sort [1, 2, 3, 4, 5]:", bubbleSort([...unsortedArray3]));​
const unsortedArray4 = [9, 8, 7, 6, 5]; ​
// Reverse sorted​
[Link]("Bubble Sort [9, 8, 7, 6, 5]:", bubbleSort([...unsortedArray4])); ​

Exercise 83: Selection Sort


// Exercise 83: Selection Sort​
function selectionSort(arr) {​
const n = [Link]; ​
// Outer loop: iterate through the array​
for (let i = 0; i < n - 1; i++) {​

Laurence Svekis Learn More [Link]


// Assume the current element is the minimum​
let minIndex = i; ​
// Inner loop: find the smallest element in the unsorted portion​
for (let j = i + 1; j < n; j++) {​
if (arr[j] < arr[minIndex]) {​
minIndex = j; ​
// Update minIndex if a smaller element is found​
}​
}​
// If the smallest element is not at the current position 'i', swap them​
if (minIndex !== i) {​
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; ​
// ES6 swap​
}​
}​
return arr; ​
// Return the sorted array​
}​
const unsortedArray1 = [64, 25, 12, 22, 11]; ​
[Link]("Selection Sort [64, 25, 12, 22, 11]:", selectionSort([...unsortedArray1]));​
const unsortedArray2 = [5, 1, 4, 2, 8]; ​
[Link]("Selection Sort [5, 1, 4, 2, 8]:", selectionSort([...unsortedArray2]));​
const unsortedArray3 = [1, 2, 3, 4, 5]; ​
// Already sorted​
[Link]("Selection Sort [1, 2, 3, 4, 5]:", selectionSort([...unsortedArray3])); ​

Exercise 84: Insertion Sort


// Exercise 84: Insertion Sort​
function insertionSort(arr) {​
const n = [Link]; ​
// Start from the second element (index 1) because the first element (index 0)​
// is considered the "sorted" part initially.​
for (let i = 1; i < n; i++) {​
let current = arr[i]; ​
// The element to be inserted into the sorted portion​
let j = i - 1; ​
// Pointer to the last element of the sorted portion​

Laurence Svekis Learn More [Link]


// Move elements of arr[0..i-1], that are greater than current,​
// to one position ahead of their current position​
while (j >= 0 && arr[j] > current) {​
arr[j + 1] = arr[j]; ​
// Shift element to the right​
j--; ​
}​
// Place current element at its correct position in the sorted part​
arr[j + 1] = current; ​
}​
return arr; // Return the sorted array​
}​
const unsortedArray1 = [12, 11, 13, 5, 6]; ​
[Link]("Insertion Sort [12, 11, 13, 5, 6]:", insertionSort([...unsortedArray1]));​
const unsortedArray2 = [5, 1, 4, 2, 8]; ​
[Link]("Insertion Sort [5, 1, 4, 2, 8]:", insertionSort([...unsortedArray2]));​
const unsortedArray3 = [1, 2, 3, 4, 5]; ​
// Already sorted (best case)​
[Link]("Insertion Sort [1, 2, 3, 4, 5]:", insertionSort([...unsortedArray3])); ​
const unsortedArray4 = [9, 8, 7, 6, 5]; // Reverse sorted (worst case)​
[Link]("Insertion Sort [9, 8, 7, 6, 5]:", insertionSort([...unsortedArray4])); ​

Exercise 85: Memoization (Simple Factorial)


// Exercise 85: Memoization (Simple Factorial)​
// Using a Map for cache for better key flexibility (though object keys work for
numbers)​
const factorialCache = new Map(); ​
function memoizedFactorial(n) {​
// Base case for recursion​
if (n === 0 || n === 1) {​
return 1; ​
}​
// Check if the result is already in the cache​
if ([Link](n)) {​
[Link](`Getting factorial(${n}) from cache.`); ​
return [Link](n);​
}​

Laurence Svekis Learn More [Link]


// If not in cache, compute the result recursively​
[Link](`Computing factorial(${n})...`); ​
const result = n * memoizedFactorial(n - 1);​
// Store the computed result in the cache before returning​
[Link](n, result); ​
return result;​
}​
[Link]("--- First set of calls ---");​
[Link]("Factorial(5):", memoizedFactorial(5)); // Will compute 5!, 4!, 3!, 2!, 1!, 0! ​
[Link]("\n--- Second set of calls (demonstrating caching) ---"); ​
[Link]("Factorial(3):", memoizedFactorial(3)); // Should use cache for 3!, 2!, 1!, 0! ​
[Link]("Factorial(6):", memoizedFactorial(6)); // Will compute 6!, then use cache
for 5! and below ​
[Link]("Factorial(5):", memoizedFactorial(5)); ​
// Should use cache directly​

Exercise 86: Simple Debounce Function


// Exercise 86: Simple Debounce Function​
function debounce(func, delay) {​
let timeoutId; ​
// This variable will store the timer ID across calls​
// Return a new function (the debounced version)​
return function(...args) { // ...args captures all arguments passed to the debounced
function​
const context = this; ​
// Capture the 'this' context of the call​
// Clear any existing timer.​
// If the debounced function is called again before the delay​
// elapses, the previous timer is cancelled, and a new one is set.​
clearTimeout(timeoutId); ​
// Set a new timer​
timeoutId = setTimeout(() => {​
// Execute the original function after the delay​
// Use .apply to correctly pass 'this' context and arguments​
[Link](context, args);​
}, delay); ​
};​

Laurence Svekis Learn More [Link]


}​
// Example Usage: Simulate a search input​
function performSearch(query) {​
[Link](`Performing search for: "${query}"...`); ​
}​
// Create a debounced version of performSearch with a 500ms delay​
const debouncedSearch = debounce(performSearch, 500); ​
[Link]("Simulating rapid typing in a search bar...");​
debouncedSearch("a");​
debouncedSearch("ap");​
debouncedSearch("app");​
setTimeout(() => debouncedSearch("appl"), 100);​
setTimeout(() => debouncedSearch("apple"), 200); ​
// This will be the only one that triggers performSearch​
setTimeout(() => [Link]("--- Finished typing simulation ---"), 1000); ​
// Another example: Button click that only triggers once​
let clickCount = 0; ​
function handleClick() {​
clickCount++;​
[Link](`Button clicked! (Actual click count: ${clickCount})`);​
}​
const debouncedClick = debounce(handleClick, 1000); ​
[Link]("\nSimulating rapid button clicks...");​
debouncedClick(); // Calls debounce, sets timer​
setTimeout(debouncedClick, 100); // Clears previous, sets new timer​
setTimeout(debouncedClick, 200); ​
// Clears previous, sets new timer​
setTimeout(debouncedClick, 300); // Clears previous, sets new timer​
// After 1000ms from the LAST call (at 300ms), handleClick will fire once.​
setTimeout(() => [Link]("--- Finished click simulation ---"), 1500); ​

Exercise 87: Simple Throttling Function


// Exercise 87: Simple Throttling Function​
function throttle(func, delay) {​
let inThrottle; ​
// Flag to indicate if we are currently in a throttled state​
let lastFn; ​

Laurence Svekis Learn More [Link]


// Stores a reference to the setTimeout callback​
let lastTime; ​
// Stores the timestamp of the last execution​
// Return a new function (the throttled version)​
return function(...args) {​
const context = this; ​
// If not currently throttled, execute immediately​
if (!inThrottle) {​
[Link](context, args); ​
lastTime = [Link]();​
inThrottle = true; // Enter throttled state​
} else {​
// If currently throttled, clear any pending execution​
clearTimeout(lastFn); ​
// Schedule a new execution after the remaining delay has passed​
// [Link] ensures the delay is at least 0, preventing negative delays​
lastFn = setTimeout(() => {​
// Check if enough time has passed since the last execution​
if (([Link]() - lastTime) >= delay) {​
[Link](context, args);​
lastTime = [Link]();​
inThrottle = false; // Exit throttled state (important for subsequent immediate
executions)​
}​
}, [Link](delay - ([Link]() - lastTime), 0)); ​
}​
};​
}​
// Example Usage: Simulate a scroll event​
function handleScroll(event) {​
[Link](`Scrolling detected! Timestamp: ${new Date().toLocaleTimeString()}`); ​
// In a real scenario, you'd do DOM updates here, e.g., update scroll position display​
}​
// Create a throttled version of handleScroll with a 1000ms (1 second) delay​
const throttledScroll = throttle(handleScroll, 1000); ​
[Link]("Simulating rapid scroll events (will only log every 1 second)...");​
throttledScroll(); // Should trigger immediately​
setTimeout(throttledScroll, 100);​
setTimeout(throttledScroll, 200); ​

Laurence Svekis Learn More [Link]


setTimeout(throttledScroll, 300);​
setTimeout(throttledScroll, 1050); // Should trigger after 1 sec​
setTimeout(throttledScroll, 1100);​
setTimeout(throttledScroll, 2200); ​
// Should trigger again after another 1 sec from previous​
setTimeout(() => [Link]("--- Finished scroll simulation ---"), 3000); ​

Exercise 88: Linked List (Basic Implementation)


// Exercise 88: Linked List (Basic Implementation)​
// Represents a single node in the linked list​
class Node {​
constructor(value) {​
[Link] = value; ​
[Link] = null; // Pointer to the next node​
}​
}​
// Manages the linked list​
class LinkedList {​
constructor() {​
[Link] = null; ​
// The first node in the list​
[Link] = null; ​
// The last node in the list​
[Link] = 0; ​
// Number of elements in the list​
}​
// Adds a new node to the end of the list​
add(value) {​
const newNode = new Node(value); ​
if (![Link]) {​
// If the list is empty, the new node is both the head and the tail​
[Link] = newNode; ​
[Link] = newNode;​
} else {​
// Otherwise, append the new node to the end and update the tail​
[Link] = newNode; ​
[Link] = newNode;​

Laurence Svekis Learn More [Link]


}​
[Link]++;​
[Link](`Added "${value}". Current size: ${[Link]}`); ​
}​
// Prints all values in the list​
print() {​
if (![Link]) {​
[Link]("Linked List is empty."); ​
return;​
}​
let current = [Link];​
let result = []; ​
while (current) {​
[Link]([Link]);​
current = [Link]; ​
// Move to the next node​
}​
[Link](`Linked List: ${[Link](" -> ")}`); ​
}​
// Finds if a value exists in the list​
find(value) {​
if (![Link]) {​
return false; ​
}​
let current = [Link];​
while (current) {​
if ([Link] === value) {​
return true; ​
// Value found​
}​
current = [Link]; ​
}​
return false; // Value not found​
}​
// Removes the first occurrence of a value​
remove(value) {​
if (![Link]) {​
[Link]("Cannot remove: List is empty."); ​
return false;​

Laurence Svekis Learn More [Link]


}​
// If the head needs to be removed​
if ([Link] === value) {​
[Link] = [Link]; ​
if (![Link]) { // If list becomes empty​
[Link] = null; ​
}​
[Link]--;​
[Link](`Removed "${value}". Current size: ${[Link]}`);​
return true; ​
}​
let current = [Link];​
while ([Link] && [Link] !== value) {​
current = [Link]; ​
}​
if ([Link]) { // Found the node to remove​
if ([Link] === [Link]) { // If removing the tail​
[Link] = current; ​
}​
[Link] = [Link];​
[Link]--;​
[Link](`Removed "${value}". Current size: ${[Link]}`);​
return true; ​
}​
[Link](`"${value}" not found for removal.`);​
return false; ​
}​
}​
// Demonstrate Linked List usage​
const myList = new LinkedList();​
[Link](); // Expected: Linked List is empty.​
[Link]("A"); ​
[Link]("B");​
[Link]("C");​
[Link](); // Expected: Linked List: A -> B -> C ​
[Link]("Does 'B' exist?", [Link]("B")); ​
// Expected: true​
[Link]("Does 'D' exist?", [Link]("D")); // Expected: false ​
[Link]("B"); // Expected: Removed "B". Current size: 2​

Laurence Svekis Learn More [Link]


[Link](); ​
// Expected: Linked List: A -> C​
[Link]("A"); // Expected: Removed "A". Current size: 1​
[Link](); ​
// Expected: Linked List: C​
[Link]("C"); // Expected: Removed "C". Current size: 0​
[Link](); // Expected: Linked List is empty. ​
[Link]("X"); // Expected: Cannot remove: List is empty. ​

Exercise 89: Tree Traversal (Depth-First Search -


Preorder)
// Exercise 89: Tree Traversal (Depth-First Search - Preorder)​
// Represents a single node in the binary tree​
class TreeNode {​
constructor(value) {​
[Link] = value; ​
[Link] = null; // Pointer to the left child node​
[Link] = null; ​
// Pointer to the right child node​
}​
}​
// Performs a Depth-First Search (DFS) in Preorder traversal​
// Preorder: Visit Root -> Traverse Left -> Traverse Right​
function preorderTraversal(node) {​
if (node === null) {​
return; ​
// Base case: if node is null, stop recursion​
}​
// 1. Visit the current node (Root)​
[Link]([Link]); ​
// 2. Traverse the left subtree​
preorderTraversal([Link]);​
// 3. Traverse the right subtree​
preorderTraversal([Link]); ​
}​
// Example Tree Structure:​
/* 10​

Laurence Svekis Learn More [Link]


/ \​
5 15​
/ \ \​
2 7 20 */​
const root = new TreeNode(10); ​
[Link] = new TreeNode(5);​
[Link] = new TreeNode(15);​
[Link] = new TreeNode(2);​
[Link] = new TreeNode(7);​
[Link] = new TreeNode(20); ​
[Link]("Preorder Traversal (Root -> Left -> Right):");​
preorderTraversal(root); // Expected: 10, 5, 2, 7, 15, 20​
// Another example tree​
/* A​
/ \​
B C​
/​
D */​
const root2 = new TreeNode('A'); ​
[Link] = new TreeNode('B');​
[Link] = new TreeNode('C');​
[Link] = new TreeNode('D');​
[Link]("\nPreorder Traversal for another tree:");​
preorderTraversal(root2); ​
// Expected: A, B, D, C​

Exercise 90: Tree Traversal (Breadth-First Search -


Level Order)
// Exercise 90: Tree Traversal (Breadth-First Search - Level Order)​
// Reusing TreeNode class from Exercise 89​
class TreeNode {​
constructor(value) {​
[Link] = value; ​
[Link] = null;​
[Link] = null;​
}​
}​

Laurence Svekis Learn More [Link]


// Performs a Breadth-First Search (BFS) / Level-Order Traversal​
function levelOrderTraversal(root) {​
if (root === null) {​
return; ​
// Base case: empty tree​
}​
// Use a queue to keep track of nodes to visit​
// (A simple array can act as a queue using push/shift)​
const queue = []; ​
[Link](root);​
[Link]("Level Order Traversal (BFS):");​
while ([Link] > 0) {​
const currentNode = [Link](); ​
// Dequeue the first node (FIFO)​
[Link]([Link]); ​
// Visit the current node​
// Enqueue its left child if it exists​
if ([Link] !== null) {​
[Link]([Link]); ​
}​
// Enqueue its right child if it exists​
if ([Link] !== null) {​
[Link]([Link]); ​
}​
}​
}​
// Example Tree Structure (same as Ex 89):​
/* 10​
/ \​
5 15​
/ \ \​
2 7 20 */​
const root = new TreeNode(10); ​
[Link] = new TreeNode(5);​
[Link] = new TreeNode(15);​
[Link] = new TreeNode(2);​
[Link] = new TreeNode(7);​
[Link] = new TreeNode(20); ​
levelOrderTraversal(root); // Expected: 10, 5, 15, 2, 7, 20​

Laurence Svekis Learn More [Link]


// Another example tree​
/* A​
/ \​
B C​
/​
D */​
const root2 = new TreeNode('A'); ​
[Link] = new TreeNode('B');​
[Link] = new TreeNode('C');​
[Link] = new TreeNode('D');​
[Link]("\nLevel Order Traversal for another tree:");​
levelOrderTraversal(root2); ​
// Expected: A, B, C, D​

Exercise 91: Currying a Function


// Exercise 91: Currying a Function​
// The original function we want to curry​
function sum(a, b, c) {​
return a + b + c; ​
}​
// The curry function​
function curry(func) {​
// Returns a new function that handles the currying logic​
return function curried(...args) {​
// If the number of arguments received is enough for the original function,​
// execute the original function with these arguments.​
if ([Link] >= [Link]) { // [Link] gives the number of expected
arguments ​
return [Link](this, args); ​
} else {​
// If not enough arguments, return another function that expects more arguments.​
// This new function will concatenate the previously received arguments with the
new ones.​
return function(...nextArgs) {​
return [Link](this, [Link](nextArgs)); ​
};​
}​

Laurence Svekis Learn More [Link]


}; ​
}​
// Demonstrate currying​
const curriedSum = curry(sum);​
[Link]("Curried Sum (one by one):", curriedSum(1)(2)(3)); ​
// Expected: 6​
[Link]("Curried Sum (two then one):", curriedSum(1, 2)(3)); ​
// Expected: 6​
[Link]("Curried Sum (all at once):", curriedSum(1, 2, 3)); ​
// Expected: 6​
// Example with another function​
function multiply(a, b, c, d) {​
return a * b * c * d; ​
}​
const curriedMultiply = curry(multiply);​
[Link]("Curried Multiply:", curriedMultiply(2)(3)(4)(5)); // Expected: 120​
[Link]("Curried Multiply:", curriedMultiply(2, 3)(4, 5)); ​
// Expected: 120​

Exercise 92: Partial Application


// Exercise 92: Partial Application​
function greet(greeting, name, punctuation) {​
[Link](`${greeting}, ${name}${punctuation}`); ​
}​
// --- Method 1: Using .bind() for partial application ---​
// .bind(thisArg, arg1, arg2, ...)​
// - The first argument is the 'this' context (null or undefined here for global functions)​
// - Subsequent arguments are prepended to the arguments of the original function​
const sayHelloWithBind = [Link](null, "Hello", "!"); ​
// Pre-fills greeting and punctuation​
[Link]("--- Using .bind() ---");​
sayHelloWithBind("Alice"); // Expected: Hello, Alice!​
sayHelloWithBind("Bob"); // Expected: Hello, Bob! ​
// --- Method 2: Manual Partial Application using a Closure ---​
// Create a higher-order function that returns a new function​
// The inner function closes over the pre-filled arguments​
function createGreeting(greeting, punctuation) {​

Laurence Svekis Learn More [Link]


return function(name) { // This is the partially applied function​
greet(greeting, name, punctuation); ​
};​
}​
const sayHiExclamatory = createGreeting("Hi", "!");​
const sayGoodMorningPeriod = createGreeting("Good morning", ".");​
[Link]("\n--- Using Closure ---"); ​
sayHiExclamatory("Charlie"); ​
// Expected: Hi, Charlie!​
sayGoodMorningPeriod("Diana"); // Expected: Good morning, Diana. ​
// Another example of partial application with bind​
function calculateDiscount(price, discountPercentage) {​
return price * (1 - discountPercentage); ​
}​
const applyTenPercentDiscount = [Link](null, 0.10); // Pre-fills
discountPercentage​
[Link]("\nPrice after 10% discount on 100:", applyTenPercentDiscount(100)); ​
// Expected: 90​
[Link]("Price after 10% discount on 250:", applyTenPercentDiscount(250)); ​
// Expected: 225​

Exercise 93: Function Composition


// Exercise 93: Function Composition​
// Simple functions to compose​
const add2 = num => num + 2; ​
const multiply3 = num => num * 3;​
const square = num => num * num; ​
const negate = num => -num;​
// The compose function (applies functions from right to left)​
function compose(...funcs) {​
// Returns a new function that takes an initial argument​
return function(initialArg) {​
// Use reduceRight to apply functions from right to left​
// The accumulator (acc) starts with initialArg​
// For each function (fn), it's called with the current accumulator's value​
return [Link]((acc, fn) => fn(acc), initialArg); ​
};​

Laurence Svekis Learn More [Link]


}​
// The pipe function (alternative, applies functions from left to right)​
function pipe(...funcs) {​
return function(initialArg) {​
return [Link]((acc, fn) => fn(acc), initialArg); ​
};​
}​
// Demonstrate composition​
const composedFunc = compose(square, multiply3, add2); ​
// (5 + 2) => 7​
// (7 * 3) => 21​
// (21 * 21) => 441​
[Link]("compose(square, multiply3, add2)(5):", composedFunc(5)); ​
// Expected: 441​
const composedAndNegated = compose(negate, square, add2); // (3 + 2) => 5​
// (5 * 5) => 25​
// (-25) => -25​
[Link]("compose(negate, square, add2)(3):", composedAndNegated(3)); ​
// Expected: -25​
// Demonstrate pipe​
const pipedFunc = pipe(add2, multiply3, square); ​
// (5 + 2) => 7​
// (7 * 3) => 21​
// (21 * 21) => 441​
[Link]("pipe(add2, multiply3, square)(5):", pipedFunc(5)); ​
// Expected: 441 (same result as compose in this specific case, but order differs)​

Exercise 94: Singleton Pattern


// Exercise 94: Singleton Pattern​
class Logger {​
// Private static field to hold the single instance​
static #instance = null; ​
// Private constructor to prevent direct instantiation​
constructor() {​
if (Logger.#instance) {​
// If an instance already exists, throw an error to prevent direct calls​
throw new Error("Logger instance already exists. Use [Link]()

Laurence Svekis Learn More [Link]


instead."); ​
}​
[Link] = []; // To store log messages​
[Link]("Logger: Initializing new instance..."); ​
}​
// Static method to get the single instance of the Logger​
static getInstance() {​
if (!Logger.#instance) {​
// If no instance exists, create one​
Logger.#instance = new Logger(); ​
}​
return Logger.#instance; // Return the existing instance​
}​
// Method to log a message​
log(message) {​
const timestamp = new Date().toISOString(); ​
const logEntry = `${timestamp} - ${message}`;​
[Link](logEntry);​
[Link](`LOG: ${logEntry}`);​
}​
// Method to get all logs​
getLogs() {​
return [Link]; ​
}​
}​
// Demonstrate the Singleton pattern​
[Link]("Attempting to get Logger instances...");​
const logger1 = [Link]();​
const logger2 = [Link](); ​
// This should return the same instance as logger1​
[Link]("\nAre logger1 and logger2 the same instance?", logger1 === logger2); ​
// Expected: true​
[Link]("Application started.");​
[Link]("User logged in.");​
[Link]("\nAll logs from logger1:", [Link]());​
[Link]("All logs from logger2:", [Link]()); ​
// Should be the same logs as logger1​
// Try to create a new instance directly (should throw an error)​
try {​

Laurence Svekis Learn More [Link]


const logger3 = new Logger(); ​
} catch (e) {​
[Link]("\nCaught an error when trying to instantiate Logger directly:",
[Link]); ​
}​

Exercise 95: Factory Pattern (Simple)


// Exercise 95: Factory Pattern (Simple)​
// 1. Define product classes (or constructor functions)​
class Car {​
constructor(options) {​
[Link] = [Link] || ​
"Generic Car";​
[Link] = [Link] || "Model X";​
[Link] = [Link] || 4; ​
}​
drive() {​
[Link](`Driving the ${[Link]} ${[Link]} (Car).`); ​
}​
}​
class Motorcycle {​
constructor(options) {​
[Link] = [Link] || "Generic Moto"; ​
[Link] = [Link] || "Model Y";​
[Link] = [Link] || 250; ​
}​
ride() {​
[Link](`Riding the ${[Link]} ${[Link]} (Motorcycle).`); ​
}​
}​
class Bicycle {​
constructor(options) {​
[Link] = [Link] || ​
"Generic Bike";​
[Link] = [Link] || "Model Z";​
[Link] = [Link] || 1; ​
}​

Laurence Svekis Learn More [Link]


pedal() {​
[Link](`Pedaling the ${[Link]} ${[Link]} (Bicycle).`); ​
}​
}​
// 2. Implement the Factory class​
class VehicleFactory {​
createVehicle(type, options) {​
switch ([Link]()) {​
case 'car':​
return new Car(options); ​
case 'motorcycle':​
return new Motorcycle(options); ​
case 'bicycle':​
return new Bicycle(options); ​
default:​
throw new Error(`Unknown vehicle type: ${type}`); ​
}​
}​
}​
// Demonstrate the Factory usage​
const factory = new VehicleFactory(); ​
const myCar = [Link]('car', { brand: 'Toyota', model: 'Camry', doors: 4 }); ​
const myMotorcycle = [Link]('motorcycle', { brand: 'Honda', model:
'CBR500R', engineCC: 500 }); ​
const myBicycle = [Link]('bicycle', { brand: 'Schwinn', model: 'Cruiser',
gears: 7 });​
[Link]("Created Vehicles:");​
[Link](myCar);​
[Link]();​
[Link](myMotorcycle);​
[Link]();​
[Link](myBicycle);​
[Link](); ​
try {​
const unknownVehicle = [Link]('boat', { brand: 'SeaRay' }); ​
} catch (e) {​
[Link]("\nCaught error for unknown vehicle type:", [Link]); ​
}​

Laurence Svekis Learn More [Link]


Exercise 96: Observer Pattern (Using Custom Event
Emitter)
// Exercise 96: Observer Pattern (Using Custom Event Emitter)​
// Reusing the EventEmitter class from Exercise 67​
class EventEmitter {​
constructor() {​
[Link] = new Map(); ​
}​
on(eventName, listener) {​
if (![Link](eventName)) {​
[Link](eventName, []); ​
}​
[Link](eventName).push(listener);​
// [Link](`[EventEmitter] Registered listener for '${eventName}'.`); ​
}​
emit(eventName, ...args) {​
const eventListeners = [Link](eventName); ​
if (eventListeners) {​
// [Link](`[EventEmitter] Emitting event '${eventName}' with args:
${[Link](args)}`);​
[Link](listener => {​
try {​
listener(...args);​
} catch (e) {​
[Link](`[EventEmitter] Error in listener for '${eventName}':`, e);​
}​
}); ​
} else {​
// [Link](`[EventEmitter] No listeners registered for '${eventName}'.`); ​
}​
}​
off(eventName, listenerToRemove) {​
const eventListeners = [Link](eventName); ​
if (eventListeners) {​
const index = [Link](listenerToRemove); ​
if (index > -1) {​
[Link](index, 1); ​

Laurence Svekis Learn More [Link]


// [Link](`[EventEmitter] Unregistered listener for '${eventName}'.`);​
} else {​
// [Link](`[EventEmitter] Listener not found for '${eventName}'.`); ​
}​
} else {​
// [Link](`[EventEmitter] No listeners registered for '${eventName}'.`); ​
}​
}​
}​
// The Subject (Publisher) that holds state and notifies observers​
class Subject {​
constructor(initialState) {​
[Link] = new EventEmitter(); ​
[Link] = initialState;​
[Link](`Subject initialized with state: ${[Link]}`);​
}​
// Method for observers to subscribe​
subscribe(listener) {​
[Link]('stateChange', listener); ​
[Link]("Observer subscribed to 'stateChange' event.");​
}​
// Method for observers to unsubscribe​
unsubscribe(listener) {​
[Link]('stateChange', listener); ​
[Link]("Observer unsubscribed from 'stateChange' event.");​
}​
// Method to change the subject's state and notify observers​
changeState(newState) {​
if ([Link] !== newState) {​
[Link] = newState; ​
[Link](`\nSubject state changed to: ${[Link]}`);​
[Link]('stateChange', [Link]); // Emit the event with the new state​
} else {​
[Link](`\nState is already '${[Link]}', no change.`); ​
}​
}​
getCurrentState() {​
return [Link]; ​
}​

Laurence Svekis Learn More [Link]


}​
// Observer functions (can be part of classes/objects too)​
const displayLogger = (newState) => [Link](`Logger: State updated to ->
${newState}`); ​
const alertUser = (newState) => {​
if (newState === 'error') {​
[Link](`ALERT: An error state was detected! Current state: ${newState}`); ​
}​
};​
const simpleReporter = (newState) => [Link](`Reporter: New state is
${newState}.`); ​
// Demonstrate the Observer pattern​
const dataSubject = new Subject("initial_status");​
// Observers subscribe to the subject​
[Link](displayLogger);​
[Link](alertUser);​
[Link](simpleReporter); ​
// Change the subject's state, which will notify all subscribed observers​
[Link]("loading");​
[Link]("data_fetched");​
[Link]("error"); ​
// This will trigger the alertUser observer​
[Link]("error"); // No change, no notification​
// Unsubscribe an observer​
[Link](displayLogger);​
[Link]("resolved"); ​
// displayLogger will no longer be notified​

Exercise 97: Mixin Pattern


// Exercise 97: Mixin Pattern​
// 1. Define the Mixin (a simple object containing methods to be mixed in)​
const LoggerMixin = {​
// The 'this' context within this method will refer to the object​
// (or class instance) that the mixin is applied to.​
log(message) {​
// Use [Link] to identify the class instance​
[Link](`[${[Link]} LOG]: ${message}`); ​

Laurence Svekis Learn More [Link]


},​
// You can add more methods or properties here​
logError(errorMsg) {​
[Link](`[${[Link]} ERROR]: ${errorMsg}`); ​
}​
};​
// 2. Define classes that will consume the mixin​
class User {​
constructor(name) {​
[Link] = name; ​
}​
greet() {​
[Link](`Hello, I am ${[Link]}.`); ​
// Uses the mixed-in log method​
}​
}​
class Product {​
constructor(name, price) {​
[Link] = name; ​
[Link] = price;​
}​
displayPrice() {​
[Link](`The price of ${[Link]} is $${[Link]}.`); ​
// Uses the mixed-in log method​
}​
}​
// 3. Apply the Mixin to the prototypes of the classes​
// [Link] copies properties from source objects to a target object. ​
// By assigning to the .prototype, all instances of User and Product will inherit these
methods.​
[Link]([Link], LoggerMixin);​
[Link]([Link], LoggerMixin); ​
// Demonstrate usage​
const user = new User("Alice");​
[Link](); // Expected: [User LOG]: Hello, I am Alice.​
[Link]("User specific activity."); ​
// Directly calling the mixed-in method​
[Link]("Failed to fetch user data."); ​
// Using another mixed-in method​

Laurence Svekis Learn More [Link]


const product = new Product("Laptop", 1200);​
[Link](); ​
// Expected: [Product LOG]: The price of Laptop is $1200.​
[Link]("Product added to cart."); ​
// Directly calling the mixed-in method​

Exercise 98: Module Pattern (Revealing Module


Pattern)
// Exercise 98: Module Pattern (Revealing Module Pattern)​
const ShoppingCart = (function() { // Immediately Invoked Function Expression (IIFE)​
// Private variables (not accessible from outside the IIFE)​
let items = [];​
let nextItemId = 1;​

// Private helper function​
function _findItemIndex(itemName) {​
return [Link](item => [Link] === itemName);​
}​

// Public methods that are exposed​
function addItem(name, price, quantity = 1) {​
const existingIndex = _findItemIndex(name); ​
if (existingIndex > -1) {​
items[existingIndex].quantity += quantity;​
[Link](`Updated quantity for "${name}".`);​
} else {​
[Link]({ id: nextItemId++, name, price, quantity });​
[Link](`Added "${name}" to cart.`);​
}​
}​

function removeItem(name) {​
const index = _findItemIndex(name);​
if (index > -1) {​
[Link](index, 1); ​
[Link](`Removed "${name}" from cart.`);​
} else {​

Laurence Svekis Learn More [Link]


[Link](`"${name}" not found in cart.`); ​
}​
}​

function getTotal() {​
return [Link]((total, item) => total + ([Link] * [Link]), 0); ​
}​

function getCartItems() {​
// Return a copy to prevent external modification of the private 'items' array​
return [...items]; ​
}​

function _clearCart() { // This could be a private helper not exposed​
items = []; ​
nextItemId = 1;​
[Link]("Cart cleared (private method).");​
}​

// The "revealing" part: expose public methods​
return {​
addItem: addItem,​
removeItem: removeItem,​
getTotal: getTotal,​
getItems: getCartItems, // Renaming for public interface​
// clear: _clearCart // Uncomment to expose a 'clear' method​
};​
})(); // The IIFE is immediately executed, and its return value is assigned to
ShoppingCart ​

// Demonstrate using the ShoppingCart module​
[Link]("--- Shopping Cart Actions ---"); ​
[Link]("Laptop", 1200);​
[Link]("Mouse", 25, 2);​
[Link]("Keyboard", 75);​
[Link]("Laptop", 1200); // Add laptop again to update quantity​
[Link]("Current cart items:", [Link]()); ​
[Link]("Cart total:", [Link]()); // Expected: 1200*2 + 25*2 + 75 =
2400 + 50 + 75 = 2525 ​

Laurence Svekis Learn More [Link]


[Link]("Mouse");​
[Link]("Cart total after removing Mouse:", [Link]()); // Expected:
2400 + 75 = 2475 ​
[Link]("Current cart items:", [Link]()); ​

// Trying to access private variables/methods directly (will fail)​
// [Link]([Link]); // Undefined​
// ShoppingCart._findItemIndex("Laptop"); ​
// TypeError​

Exercise 99: Higher-Order Components (Conceptual)


// Exercise 99: Higher-Order Components (Conceptual)​
// 1. Definition of a "Component" (as a simple function for this conceptual example)​
// In React, this would be a React component (functional or class-based).​
const UserProfileComponent = (props) => {​
[Link](`Rendering UserProfile for: ${[Link]}, Status:
${[Link]}`);​
return `<div><h1>User Profile for ${[Link]}</h1><p>Status:
${[Link]}</p></div>`; ​
};​
// 2. The Higher-Order Component (HOC)​
// A HOC is a function that takes a component (WrappedComponent)​
// and returns a new component with enhanced functionality.​
function withLoading(WrappedComponent) {​
// The HOC returns a new functional component​
return function EnhancedComponent(props) {​
if ([Link]) {​
[Link]("Displaying loading state..."); ​
return "<div>Loading...</div>"; // Render loading UI​
} else if ([Link]) {​
[Link]("Displaying error state..."); ​
return `<div>Error: ${[Link] || 'Something went wrong.'}</div>`; //
Render error UI​
} else {​
// If not loading and no error, render the original component with its props​
[Link]("Rendering wrapped component."); ​
// In a real React app, you'd use <WrappedComponent {...props} />​

Laurence Svekis Learn More [Link]


// Here, we just call the function as a stand-in.​
return WrappedComponent(props); ​
}​
};​
}​
// 3. Applying the HOC​
// Create an enhanced version of UserProfileComponent​
const EnhancedUserProfile = withLoading(UserProfileComponent); ​
// Demonstrate usage of the Enhanced Component​
[Link]("--- First Render (Loading) ---");​
[Link](EnhancedUserProfile({ isLoading: true })); ​
// Expected: <div>Loading...</div>​
[Link]("\n--- Second Render (Data Loaded) ---"); ​
[Link](EnhancedUserProfile({ isLoading: false, userName: "Alice", status: "Active"
})); ​
// Expected: <div><h1>User Profile for Alice</h1><p>Status: Active</p></div>​
[Link]("\n--- Third Render (Error) ---"); ​
[Link](EnhancedUserProfile({ isLoading: false, error: new Error("Network failed")
})); ​
// Expected: <div>Error: Network failed</div>​
[Link]("\n--- Fourth Render (No Data, No Error) ---"); ​
[Link](EnhancedUserProfile({ isLoading: false, userName: "Bob", status:
"Inactive" })); ​

Exercise 100: Web Workers (Conceptual)


// Exercise 100: Web Workers (Conceptual)​
[Link]("--- Web Workers Conceptual Example ---"); ​
[Link]("Web Workers allow JavaScript code to run in a background thread,
separate from the main execution thread."); ​
[Link]("This prevents heavy computations from blocking the UI (main thread),
keeping the page responsive."); ​
[Link]("They do NOT have direct access to the DOM or window object."); ​
[Link]("Communication between the main thread and a worker happens via
messages."); ​
// --- Conceptual [Link] code ---​
[Link]("\n--- Main Thread (simulated) ---"); ​
[Link]("Main thread: Starting a heavy calculation in a Web Worker..."); ​

Laurence Svekis Learn More [Link]


// Imagine [Link] contains the heavy computation logic​
// const myWorker = new Worker('[Link]');​
// In a real browser, this would create the worker​
// Simulate worker communication (since we can't spawn actual workers here)​
function simulateWorkerCommunication(workerFile, dataToPost) {​
[Link]("Main thread: Sending data to simulated worker:", dataToPost); ​
// Simulate the worker's onmessage​
setTimeout(() => {​
[Link]("Simulated Worker: Received message from main thread.");​
// Simulate the heavy calculation​
const result = performHeavyCalculation([Link]); // Calls the heavy
function defined below​
[Link]("Simulated Worker: Sending result back to main thread.");​
// Simulate the worker's postMessage​
setTimeout(() => {​
[Link]("Main thread: Received result from simulated worker:", result);​
[Link]("Main thread: UI remains responsive during heavy calculation.");​
}, 50); // Small delay to simulate message passing overhead​
}, 100); ​
}​
// --- Heavy Calculation (would typically be in [Link]) ---​
function performHeavyCalculation(num) {​
[Link]("Worker: Performing heavy calculation..."); ​
let sum = 0;​
// This loop will block the worker thread, but not the main browser UI thread​
for (let i = 0; i < num; i++) {​
sum += [Link](i) * [Link](i + 1); ​
// A somewhat CPU-intensive calculation​
}​
return `Calculated sum of ${[Link](2)} for ${num} iterations.`; ​
}​
// Start the simulated heavy computation​
simulateWorkerCommunication("[Link]", { type: 'startCalculation', data: 10000000
}); ​
// A large number for computation​
[Link]("Main thread: This message appears immediately, demonstrating
non-blocking behavior."); ​
[Link]("Main thread: User can interact with the page while calculation is in
progress."); ​

Laurence Svekis Learn More [Link]


// Benefits of Web Workers:​
[Link]("\nBenefits of Web Workers:");​
[Link]("- **Improved UI Responsiveness:** Prevents the main thread from
freezing during long-running tasks."); ​
[Link]("- **Parallel Execution:** Achieves a form of multi-threading in the
browser.");​
[Link]("- **Better Performance:** Distributes workload across threads."); ​

Laurence Svekis Learn More [Link]

You might also like