-
Section 1: Getting Started
-
Section 2: Core Syntax and Types
-
Section 3: Strings and Numbers in Depth
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Objects and Arrays
-
Section 7: Maps, Sets, and Symbols
-
Section 8: Asynchronous JavaScript
-
Section 9: Object-Oriented and Prototypes
-
Section 10: The DOM
-
Section 11: Browser APIs
-
Section 12: Modern JavaScript (ES2015-ES2025)
-
Section 13: Functional Programming Patterns
-
Section 14: Error Handling and Debugging
-
Section 15: Testing
-
Section 16: Accessibility for JavaScript Developers
-
Section 17: Internationalization and Localization
-
Section 18: Performance
-
Section 19: Node.js Fundamentals
-
Section 20: Regular Expressions
-
Section 21: Design Patterns in JavaScript
-
Section 22: Security Basics
-
Section 23: Data Structures and Algorithms in JavaScript
-
Section 24: Practical Projects
-
Section 25: More Advanced Async Patterns
-
Section 26: More Object and Class Practice
-
Section 27: Working with Dates and Internationalization
-
Section 28: Web Components
-
Section 29: More DOM and Browser Practice
-
Section 30: Build Tooling for Vanilla JavaScript
-
Section 31: More Practice Projects
-
Section 32: Interview and Algorithm Practice
-
Section 33: Error Objects (MDN Reference)
-
Section 34: TypedArrays and Binary Data
-
Section 35: Reflection and Metaprogramming (MDN Reference)
-
Section 36: More Global Functions (MDN Reference)
50: Practice Exercise: Building a Shopping Cart with Array Methods
Think of a shopping cart not as a static list, but as a conveyor belt at a grocery store. As items move toward the register, things happen to them in a sequence. A clerk might pull out a spoiled apple (filtering), the scanner might apply a "buy-one-get-one" discount to every soda bottle (mapping), and finally, the register adds everything up into one single grand total (reducing).
In JavaScript, we don't want to use for loops to handle these tasks. They're too verbose and prone to "off-by-one" errors. Instead, we use array methods that describe what we want to happen, rather than how to increment a counter. Here is how that conveyor belt maps to your code:
- Filtering is your "quality control." You tell JS: "Keep only the items that meet this condition, and toss the rest."
- Mapping is your "transformation." You tell JS: "Take every item in this list and change it into something else (or a modified version of itself) without changing the number of items."
- Reducing is your "accumulator." You tell JS: "Squash this entire list down into one single value—like a price total or a final count."
Sifting through the clutter
When a user removes an item from a cart, we don't usually "delete" it in place. That can lead to weird bugs with state. Instead, we filter the array to create a new one that simply doesn't include that specific item. I always find this cleaner because it treats your data as immutable.
const cart = [
{ id: 1, name: 'Mechanical Keyboard', price: 150 },
{ id: 2, name: 'Gaming Mouse', price: 80 },
{ id: 3, name: 'UltraWide Monitor', price: 400 }
];
// Let's say the user removes the mouse (id: 2)
const updatedCart = cart.filter(item => item.id !== 2);
// Result: Keyboard and Monitor remain.
Applying a store-wide sale
Now, imagine you have a promo code that takes 10% off everything. You wouldn't want to loop through the array and manually update each price. That's where .map() shines. It creates a brand new array where every single element has been put through the same logic.
const discountedCart = cart.map(item => ({
...item,
price: item.price * 0.9
}));
// I used the spread operator (...) here so we keep the name and id
// while only updating the price.
The final tally
This is where people usually struggle. .reduce() feels intimidating because the syntax is a bit clunky, but it's actually the most powerful tool in your kit. Think of it as a snowball rolling down a hill. The "accumulator" is the snowball, and the "current value" is the fresh snow it picks up as it goes.
const totalCost = cart.reduce((accumulator, item) => {
return accumulator + item.price;
}, 0);
// That '0' at the end is crucial. It's the starting value of our snowball.
// If you forget it, JS will use the first object in the array as the start,
// and you'll end up with a weird string like "[object Object]80400".
When you combine these three, you can handle almost any data manipulation task. You filter the unwanted, map the changes, and reduce the result. It's a pipeline—clean, readable, and professional.
📋 Practical Task
The Gourmet Grocery Checkout Logic
You are building the backend logic for a high-end grocery app. You have an array of items in the user's cart, but some items are "out of stock" and need to be removed, and a "Loyalty Discount" needs to be applied to the remaining items before calculating the total.
Your Goal: Write a script that processes the following cart:
const groceryCart = [
{ name: 'Truffle Oil', price: 30, inStock: true },
{ name: 'Saffron', price: 50, inStock: false },
{ name: 'Aged Balsamic', price: 40, inStock: true },
{ name: 'Caviar', price: 100, inStock: false },
{ name: 'Wagyu Beef', price: 120, inStock: true },
];
Requirements:
- Use
.filter()to create a new array containing only items whereinStockistrue. - Use
.map()on that filtered array to apply a 20% discount to the price of every item. - Use
.reduce()on the discounted array to calculate the final grand total. - Log the final total to the console.
There are no comments for now.