Advanced JavaScript Concepts
Optional Deep Dive Material for Session 2 (Optional)
Course lectures and practices for JavaScript full‑stack web development with AI‑assisted workflows.
This document contains advanced JavaScript concepts that were moved from the main Session 2 lecture to keep the core session focused and manageable.
Prerequisites: Complete Session 2 main content first.
When to read: When you’re comfortable with JavaScript basics and want to deepen your understanding before or after Session 3.
Advanced Array Methods
Beyond map() and filter()
While Session 2 covers basic map()
and filter()
, here are additional powerful array methods:
reduce() - The Swiss Army Knife
// Calculate total price
const prices = [19.99, 29.99, 39.99];
const total = prices.reduce((sum, price) => sum + price, 0);
// Result: 89.97
// Group reviews by rating
const reviews = [
rating: 5, comment: "Great!" },
{ rating: 4, comment: "Good" },
{ rating: 5, comment: "Excellent!" }
{ ;
]
const groupedByRating = reviews.reduce((groups, review) => {
const rating = review.rating;
if (!groups[rating]) groups[rating] = [];
.push(review);
groups[rating]return groups;
, {});
}// Result: { 4: [...], 5: [...] }
find() and findIndex()
// Find specific review
const reviews = [
id: 1, rating: 5 },
{ id: 2, rating: 3 },
{ id: 3, rating: 4 }
{ ;
]
const highRating = reviews.find(review => review.rating >= 4);
// Result: { id: 1, rating: 5 }
const index = reviews.findIndex(review => review.id === 2);
// Result: 1
some() and every()
// Check if any review is 5 stars
const hasExcellentReview = reviews.some(review => review.rating === 5);
// Check if all reviews are positive (>= 3)
const allPositive = reviews.every(review => review.rating >= 3);
Advanced Error Handling
Try-Catch Patterns
Async Error Handling
// Basic pattern (covered in Session 2)
async function fetchReviews() {
try {
const response = await fetch('/api/reviews');
const data = await response.json();
return data;
catch (error) {
} console.error('Error:', error);
return [];
}
}
// Advanced pattern with specific error types
async function fetchReviewsAdvanced(productId) {
try {
const response = await fetch(`/api/products/${productId}/reviews`);
if (!response.ok) {
if (response.status === 404) {
throw new Error('Product not found');
else if (response.status === 500) {
} throw new Error('Server error - please try again later');
else {
} throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
}
const data = await response.json();
return data;
catch (error) {
} if (error instanceof TypeError) {
// Network error
throw new Error('Network error - check your connection');
}throw error; // Re-throw other errors
} }
Error Boundaries in Vanilla JS
// Global error handler
window.addEventListener('error', (event) => {
console.error('Global error:', event.error);
// Send to logging service
// Show user-friendly message
;
})
// Unhandled promise rejection handler
window.addEventListener('unhandledrejection', (event) => {
console.error('Unhandled promise rejection:', event.reason);
event.preventDefault(); // Prevent console error
; })
Browser Storage APIs
localStorage and sessionStorage
Basic Usage
// Save user preferences
const userPrefs = {
theme: 'dark',
itemsPerPage: 10,
sortBy: 'rating'
;
}
.setItem('userPrefs', JSON.stringify(userPrefs));
localStorage
// Retrieve preferences
const savedPrefs = JSON.parse(localStorage.getItem('userPrefs') || '{}');
Shopping Cart Implementation
class ShoppingCart {
constructor() {
this.items = this.loadFromStorage();
}
addItem(product) {
const existingItem = this.items.find(item => item.id === product.id);
if (existingItem) {
.quantity += 1;
existingItemelse {
} this.items.push({ ...product, quantity: 1 });
}
this.saveToStorage();
this.updateUI();
}
removeItem(productId) {
this.items = this.items.filter(item => item.id !== productId);
this.saveToStorage();
this.updateUI();
}
loadFromStorage() {
try {
return JSON.parse(localStorage.getItem('cart') || '[]');
catch (error) {
} console.error('Error loading cart:', error);
return [];
}
}
saveToStorage() {
try {
.setItem('cart', JSON.stringify(this.items));
localStoragecatch (error) {
} console.error('Error saving cart:', error);
}
}
updateUI() {
// Update cart display
const cartElement = document.querySelector('#cart-items');
if (cartElement) {
.innerHTML = this.items.map(item => `
cartElement <div class="cart-item">
<span>${item.name}</span>
<span>Qty: ${item.quantity}</span>
<span>$${(item.price * item.quantity).toFixed(2)}</span>
</div>
`).join('');
}
}
}
// Usage
const cart = new ShoppingCart();
Advanced DOM Manipulation
Event Delegation
Instead of adding event listeners to every button:
// ❌ Bad: Multiple event listeners
document.querySelectorAll('.review-like-btn').forEach(btn => {
.addEventListener('click', handleLike);
btn;
})
// ✅ Good: Single delegated event listener
document.addEventListener('click', (event) => {
if (event.target.matches('.review-like-btn')) {
handleLike(event);
}; })
Creating Complex Elements
function createReviewCard(review) {
const card = document.createElement('div');
.className = 'review-card bg-white p-4 rounded-lg shadow';
card
// Create star rating
const stars = Array.from({ length: 5 }, (_, i) => {
const star = document.createElement('span');
.className = i < review.rating ? 'star-filled' : 'star-empty';
star.textContent = '★';
starreturn star;
;
})
const starsContainer = document.createElement('div');
.className = 'flex gap-1';
starsContainer.append(...stars);
starsContainer
// Create content
const title = document.createElement('h3');
.textContent = review.title;
title.className = 'font-bold text-lg';
title
const content = document.createElement('p');
.textContent = review.content;
content.className = 'text-gray-700 mt-2';
content
const author = document.createElement('div');
.textContent = `By ${review.author} on ${review.date}`;
author.className = 'text-sm text-gray-500 mt-2';
author
// Assemble card
.append(starsContainer, title, content, author);
card
return card;
}
Performance Optimization
Debouncing and Throttling
Search Input Debouncing
function debounce(func, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
= setTimeout(() => func.apply(this, args), delay);
timeoutId ;
}
}
// Usage for search
const searchInput = document.querySelector('#search');
const debouncedSearch = debounce(performSearch, 300);
.addEventListener('input', (event) => {
searchInputdebouncedSearch(event.target.value);
;
})
function performSearch(query) {
console.log('Searching for:', query);
// Perform actual search
}
Scroll Event Throttling
function throttle(func, delay) {
let timeoutId;
let lastExecTime = 0;
return function (...args) {
const currentTime = Date.now();
if (currentTime - lastExecTime > delay) {
.apply(this, args);
func= currentTime;
lastExecTime else {
} clearTimeout(timeoutId);
= setTimeout(() => {
timeoutId .apply(this, args);
func= Date.now();
lastExecTime , delay - (currentTime - lastExecTime));
}
};
}
}
// Usage for scroll events
const throttledScrollHandler = throttle(handleScroll, 100);
window.addEventListener('scroll', throttledScrollHandler);
Modern JavaScript Features
Optional Chaining
// Safe property access
const userCity = user?.profile?.address?.city;
// Safe method calls
const result = api.getData?.();
// Safe array access
const firstReview = reviews?.[0];
Nullish Coalescing
// Use default only for null/undefined
const username = user.name ?? 'Anonymous';
const port = process.env.PORT ?? 3000;
// Different from || operator
const count = 0;
console.log(count || 10); // 10 (falsy)
console.log(count ?? 10); // 0 (not nullish)
Destructuring Patterns
// Array destructuring with rest
const [first, second, ...rest] = reviews;
// Object destructuring with renaming
const { title: reviewTitle, rating: stars } = review;
// Nested destructuring
const { user: { name, profile: { age } } } = reviewData;
// Function parameter destructuring
function displayReview({ title, rating, author = 'Anonymous' }) {
console.log(`${title} - ${rating} stars by ${author}`);
}
When to Use These Advanced Features
In React Development: - Array methods: Essential for rendering lists and data manipulation - Error handling: Critical for user experience - Storage APIs: Less needed (React has state management) - DOM manipulation: Rarely needed (React handles DOM) - Performance: React has built-in optimizations
Recommendation: Focus on array methods and error handling first. The other topics become more relevant in specialized scenarios or when working outside React.