Loops and modern methods in Javascript Programming

Abstract: In this article, we’re going to explore loops and ready-to-use methods in JavaScript. And it’s not just going to be all theory. We’ll also look at examples and real-life situations to see how loops work in action.

By Javascript Diary

August 13, 2023

Can you imagine a programming language without loops? Imagine if I asked you to write code for a real-time application without using any loops. Would that be doable? Probably not. Loops are like essential tools in programming. They help you go through lists, collections, and objects, whether they’re small or large.

In today’s world of data-driven software, no matter what programming language you use, understanding loops is really important. Knowing how loops work, where to use them, their limitations, and the best ways to use them can make your code strong and fast.

for Loop:

The traditional for loop is used for iterating over a sequence of numbers or elements. It consists of three parts: initialization, condition, and iteration statement.

Use Cases: Ideal for iterating over iterable objects like arrays, strings, maps, and sets.
Constraints/Best Practices: Avoid using it when you need an index or access to the original array index. It’s not suitable for iterating over object properties.

Example: Simulating a complex mathematical sequence and analyzing its patterns.

				
					const sequence = [];
for (let i = 1; i <= 10; i++) {
    sequence.push(2 * i - 1);
}
				
			

while Loop:

The while loop repeatedly executes a block of code as long as a specified condition is true.
Use Cases: Suitable when you want to repeatedly execute a block of code based on a condition.
Constraints/Best Practices: Be cautious to ensure that the loop condition eventually becomes false, or the loop will run indefinitely.

Example: Simulating a financial investment and tracking its growth over time.

				
					const initialInvestment = 1000;
const annualInterestRate = 0.05;
const targetAmount = 1500;
let years = 0;
let balance = initialInvestment;
while (balance < targetAmount) {
    balance *= (1 + annualInterestRate);
    years++;
}

				
			

do...while Loop:

Similar to the while loop, the do…while loop executes a block of code at least once, and then continues to execute as long as the specified condition is true.

Use Cases: Similar to a while loop, but guarantees that the code block runs at least once.
Constraints/Best Practices: Use it when you want to ensure that the code block executes before checking the loop condition.

Example: User authentication with a limited number of login attempts.

				
					const allowedUsername = 'admin';
const allowedPassword = 'p@ssw0rd';
let attempts = 0;
let loggedIn = false;
do {
    const enteredUsername = prompt('Enter your username:');
    const enteredPassword = prompt('Enter your password:');
    if (enteredUsername === allowedUsername && enteredPassword === allowedPassword) {
        loggedIn = true;
    } else {
        attempts++;
    }
} while (!loggedIn && attempts < 3);
				
			

for...of Loop:

The for…of loop is used to iterate over the values of an iterable object such as arrays, strings, maps, sets, etc. It provides a simpler syntax and eliminates the need for an index or counter.

Use Cases: Ideal for iterating over iterable objects like arrays, strings, maps, and sets.
Constraints/Best Practices: Avoid using it when you need an index or access to the original array index. It’s not suitable for iterating over object properties.

Example: Analyzing a collection of stock prices and calculating the average.

				
					const stockPrices = [120.50, 125.75, 130.20, 122.80, 128.40];
let total = 0;
for (const price of stockPrices) {
    total += price;
}
const averagePrice = total / stockPrices.length;

				
			
In most cases, when you are working with arrays or collections where order matters, for…of is a more suitable choice. When you’re working with objects and need to examine their properties, for…in can be more appropriate.

for...in Loop:

The for…in loop is used to iterate over the enumerable properties of an object. It’s typically used with objects and can also iterate over the prototype chain. Unlikely for of you can not use it on the array.

Use Cases: Useful for enumerating properties of an object.
Constraints/Best Practices: Be cautious when using it on arrays, as it can also iterate over inherited properties. Additionally, avoid using it when the order of properties is important, as the order is not guaranteed.

Example: Creating a deep copy of a nested object while preserving its structure.

				
					function deepCopy(obj) {
    const newObj = {};
    for (const key in obj) {
        if (typeof obj[key] === 'object') {
            newObj[key] = deepCopy(obj[key]);
        } else {
            newObj[key] = obj[key];
        }
    }
    return newObj;
}
				
			

forEach() Method:

Arrays have a built-in forEach() method that allows you to iterate over each element in the array. This method takes a callback function and is often used for its concise syntax.

Use Cases: Great for performing an action on each element of an array.
Constraints/Best Practices: It cannot be used for early termination or skipping elements, as it iterates through all elements.

Example: Analyzing customer orders and generating a report with item details

				
					const orders = [
{ id: 1, items: [{ name: 'Shirt', price: 25 }, { name: 'Jeans', price: 50 }] },
{ id: 2, items: [{ name: 'Shoes', price: 80 }, { name: 'Hat', price: 15 }] }
];
orders.forEach(order => {
console.log(`Order ${order.id}:`);
order.items.forEach(item => {
console.log(` ${item.name}: $${item.price}`);
});
});
				
			

map() Method:

The map() method creates a new array by applying a provided callback function to each element in the original array. It’s commonly used for transforming elements in an array.

Use Cases: Useful for transforming elements in an array and creating a new array.
Constraints/Best Practices: Ensure that the callback function doesn’t modify the external state, as the primary purpose of map() is to produce a new array.

Example: Transforming raw data from a server response into structured objects.

				
					const rawData = [
{ id: 1, title: 'Article 1', content: 'Lorem ipsum...' },
{ id: 2, title: 'Article 2', content: 'Dolor sit amet...' }
];
const articles = rawData.map(data => ({ id: data.id, title: data.title }));
				
			

filter() Method:

The filter() method creates a new array with all elements that pass a test implemented by the provided callback function. It’s used for selecting elements that meet certain criteria.

Use Cases: Suitable for selecting elements from an array based on certain criteria.
Constraints/Best Practices: Like map(), ensure that the callback function doesn’t modify the external state, as filter() is intended for selection, not modification.

Example: Filtering out irrelevant data from a list of user notifications.

				
					const notifications = [
{ type: 'email', message: 'New message from John' },
{ type: 'sms', message: 'Meeting reminder' },
{ type: 'email', message: 'Payment received' }
];
const importantNotifications = notifications.filter(notification => notification.type === 'email');
				
			

reduce() Method:

The reduce() method applies a callback function to each element of an array, resulting in a single accumulated value. It’s commonly used for tasks like summing up elements or performing calculations.

Use Cases: Ideal for accumulating values or reducing an array to a single value.
Constraints/Best Practices: Use it when you need to perform calculations that involve interactions between elements in the array.

Example: Aggregating data from multiple sensor readings to calculate an average value.

				
					const sensorReadings = [23.5, 24.0, 23.8, 23.2, 24.5];
const total = sensorReadings.reduce(
(sum, reading) =>
{
   return sum + reading
}, 0);

const averageReading = total/sensorReadings.length;
				
			

find() Method

The find() method returns the first element in an array that satisfies a provided testing function. It’s used for searching and retrieving elements from an array.

Use Cases: Effective for searching and retrieving the first element that matches a condition.
Constraints/Best Practices: Use it when you need to find a specific element in an array based on a condition.
Example: Searching a database for a user’s profile with a specific attribute.

				
					const profiles = [
{ id: 1, username: 'alice123', status: 'active' },
{ id: 2, username: 'bob456', status: 'inactive' }
];
const activeUserProfile = profiles.find(profile => profile.status === 'active');
				
			

some() and every() Method:

The some() method checks if at least one element in the array satisfies a given condition, while the every() method checks if all elements satisfy the condition.

Use Cases: Suitable for checking if certain conditions are met within an array.
Constraints/Best Practices: Use them when you want to perform boolean checks on array elements.
Example: Verifying if any users in a list have confirmed their email addresses.

				
					const users = [
{ name: 'Alice', emailConfirmed: true },
{ name: 'Bob', emailConfirmed: false },
{ name: 'Charlie', emailConfirmed: true }
];
const hasConfirmedEmail = users.some(user => user.emailConfirmed);
const allEmailsConfirmed = users.every(user => user.emailConfirmed);
				
			

Conclusion:

The focus of this article was to learn all available loops and methods and their examples. we also learned the constraints and best practices of using them.