🔥 JavaScript Intermediate

Level Up Your Skills - Advanced Concepts & Techniques

Ready to go beyond the basics? This intermediate course builds on your JavaScript fundamentals and introduces powerful concepts used by professional developers.

🎯 Course Prerequisites

This course assumes you know:

If you need to review: Start with the Beginner Course

🎯 Module 8: Control Flow Mastery

Advanced decision making and loops

🔀 Advanced If/Else Statements

Think of if/else like a choose-your-own-adventure book.

Based on the reader's choices, the story goes different directions. Similarly, if/else statements let your program make decisions and execute different code paths.

// Basic if/else let age = 25; if (age >= 18) { console.log("You can vote!"); } else { console.log("Too young to vote"); } // Nested if/else let temperature = 75; if (temperature > 90) { console.log("It's hot! Stay inside."); } else if (temperature > 70) { console.log("Perfect weather!"); } else if (temperature > 50) { console.log("A bit chilly"); } else { console.log("Brrr! Bundle up!"); } // Ternary operator (shortcut for simple if/else) let canDrive = age >= 16 ? "Yes, you can drive" : "No, too young"; console.log(canDrive); // Switch statement (great for multiple options) let day = "Monday"; switch (day) { case "Monday": console.log("Start of work week"); break; case "Friday": console.log("TGIF!"); break; case "Saturday": case "Sunday": console.log("Weekend!"); break; default: console.log("Regular workday"); }

🔄 Advanced Loops

// For loop (when you know how many times) for (let i = 0; i < 5; i++) { console.log("Count:", i); } // While loop (when you don't know how many times) let count = 0; while (count < 3) { console.log("While count:", count); count++; } // Do-while (runs at least once) let number; do { number = Math.floor(Math.random() * 10); console.log("Random number:", number); } while (number !== 5); // For-of loop (modern way to iterate arrays) let fruits = ["apple", "banana", "orange"]; for (let fruit of fruits) { console.log("I like", fruit); } // For-in loop (for objects) let person = { name: "Alice", age: 25, city: "NYC" }; for (let key in person) { console.log(key + ":", person[key]); } // Break and continue for (let i = 0; i < 10; i++) { if (i === 3) continue; // Skip 3 if (i === 7) break; // Stop at 7 console.log(i); }

🎉 Control Flow Challenge!

Create a program that:

  1. Checks if a number is positive, negative, or zero
  2. Uses a switch statement for days of the week
  3. Creates a countdown from 10 to 1 using a loop
  4. Finds the largest number in an array

🎯 Module 9: Functions Deep Dive

Master function patterns and advanced concepts

🔧 Function Parameters & Arguments

// Default parameters function greet(name = "Guest", time = "day") { return `Good ${time}, ${name}!`; } console.log(greet()); // "Good day, Guest!" console.log(greet("Alice")); // "Good day, Alice!" console.log(greet("Bob", "evening")); // "Good evening, Bob!" // Rest parameters (collects multiple arguments) function sum(...numbers) { return numbers.reduce((total, num) => total + num, 0); } console.log(sum(1, 2, 3)); // 6 console.log(sum(10, 20, 30, 40)); // 100 // Spread operator with functions let numbers = [1, 2, 3, 4, 5]; console.log(Math.max(...numbers)); // 5 (spreads array as arguments)

📚 Function Scope & Closures

Think of closures like a backpack you carry around.

Even when you're far from home, you still have access to everything in your backpack. Closures let functions "remember" variables from their creation context.

// Global scope let globalVar = "I'm global"; function outerFunction() { let outerVar = "I'm from outer function"; function innerFunction() { let innerVar = "I'm from inner function"; console.log(innerVar); // Can access innerVar console.log(outerVar); // Can access outerVar console.log(globalVar); // Can access globalVar } innerFunction(); // console.log(innerVar); // Error! Can't access innerVar here } outerFunction(); // Closure example function createCounter() { let count = 0; // This variable is "closed over" return function() { count++; return count; }; } let counter1 = createCounter(); let counter2 = createCounter(); console.log(counter1()); // 1 console.log(counter1()); // 2 console.log(counter2()); // 1 (separate counter!)

🚀 Higher-Order Functions

// Functions that take functions as parameters function processArray(array, callback) { let result = []; for (let item of array) { result.push(callback(item)); } return result; } let numbers = [1, 2, 3, 4, 5]; let doubled = processArray(numbers, x => x * 2); console.log(doubled); // [2, 4, 6, 8, 10] let squared = processArray(numbers, x => x ** 2); console.log(squared); // [1, 4, 9, 16, 25] // Functions that return functions function createMultiplier(multiplier) { return function(number) { return number * multiplier; }; } let double = createMultiplier(2); let triple = createMultiplier(3); console.log(double(5)); // 10 console.log(triple(5)); // 15

🎯 Module 10: Arrays Power User

Master array methods and advanced techniques

🔧 Essential Array Methods

let fruits = ["apple", "banana", "orange"]; // Adding/removing elements fruits.push("grape"); // Add to end: ["apple", "banana", "orange", "grape"] fruits.unshift("mango"); // Add to start: ["mango", "apple", "banana", "orange", "grape"] fruits.pop(); // Remove from end: ["mango", "apple", "banana", "orange"] fruits.shift(); // Remove from start: ["apple", "banana", "orange"] // Finding elements console.log(fruits.indexOf("banana")); // 1 console.log(fruits.includes("apple")); // true console.log(fruits.find(fruit => fruit.length > 5)); // "banana" // Slicing and splicing let numbers = [1, 2, 3, 4, 5]; console.log(numbers.slice(1, 4)); // [2, 3, 4] (doesn't modify original) numbers.splice(2, 2, 10, 20); // Replace 2 elements with new ones console.log(numbers); // [1, 2, 10, 20, 5]

🔄 Iteration Methods

let numbers = [1, 2, 3, 4, 5]; // forEach - Execute function for each element numbers.forEach(num => console.log(num * 2)); // map - Transform each element let doubled = numbers.map(num => num * 2); console.log(doubled); // [2, 4, 6, 8, 10] // filter - Keep only elements that pass test let evenNumbers = numbers.filter(num => num % 2 === 0); console.log(evenNumbers); // [2, 4] // reduce - Combine all elements into single value let sum = numbers.reduce((total, num) => total + num, 0); console.log(sum); // 15 let max = numbers.reduce((max, num) => num > max ? num : max); console.log(max); // 5 // some/every - Test conditions console.log(numbers.some(num => num > 3)); // true (at least one > 3) console.log(numbers.every(num => num > 3)); // false (not all > 3)

🎯 Module 7: Objects & Classes

Object-oriented programming in JavaScript

🏗️ Constructor Functions & Classes

// Constructor function (old way) function Person(name, age) { this.name = name; this.age = age; this.greet = function() { return `Hello, I'm ${this.name}`; }; } let alice = new Person("Alice", 25); console.log(alice.greet()); // "Hello, I'm Alice" // Class syntax (modern way) class Person { constructor(name, age) { this.name = name; this.age = age; } greet() { return `Hello, I'm ${this.name}`; } celebrateBirthday() { this.age++; return `Happy birthday! Now ${this.age} years old.`; } } let bob = new Person("Bob", 30); console.log(bob.greet()); console.log(bob.celebrateBirthday());

🔗 Prototypes & Inheritance

// Inheritance with classes class Animal { constructor(name) { this.name = name; } speak() { return `${this.name} makes a sound`; } } class Dog extends Animal { constructor(name, breed) { super(name); // Call parent constructor this.breed = breed; } speak() { return `${this.name} barks!`; // Override parent method } fetch() { return `${this.name} fetches the ball!`; } } let dog = new Dog("Buddy", "Golden Retriever"); console.log(dog.speak()); // "Buddy barks!" console.log(dog.fetch()); // "Buddy fetches the ball!"

⚡ Module 11: Asynchronous JavaScript

Handling time and asynchronous operations

⏰ Understanding Asynchronous Code

Think of asynchronous code like ordering food at a restaurant.

You place your order (start async operation), then continue chatting with friends while waiting. When food arrives (operation completes), you get notified and can eat.

// Synchronous (blocking) - one thing at a time console.log("Start"); console.log("Middle"); console.log("End"); // Output: Start, Middle, End // Asynchronous (non-blocking) - can do other things while waiting console.log("Start"); setTimeout(() => { console.log("This happens later"); }, 1000); console.log("End"); // Output: Start, End, "This happens later"

📋 Promises

// Creating a promise function delay(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); } // Using promises delay(1000) .then(() => { console.log("1 second passed"); return delay(500); }) .then(() => { console.log("Another 0.5 seconds passed"); }) .catch(error => { console.error("Something went wrong:", error); }); // Promise with resolve/reject function fetchUserData(userId) { return new Promise((resolve, reject) => { // Simulate API call setTimeout(() => { if (userId > 0) { resolve({ id: userId, name: "John Doe" }); } else { reject(new Error("Invalid user ID")); } }, 1000); }); } fetchUserData(123) .then(user => console.log("User:", user)) .catch(error => console.error("Error:", error));

⚡ Async/Await

// Async function async function getUserData() { try { console.log("Fetching user..."); let user = await fetchUserData(456); console.log("User data:", user); console.log("Fetching posts..."); let posts = await fetchPosts(user.id); console.log("Posts:", posts); } catch (error) { console.error("Error:", error); } } // Async function that returns a promise async function fetchPosts(userId) { return new Promise(resolve => { setTimeout(() => { resolve([ { id: 1, title: "My first post" }, { id: 2, title: "Another post" } ]); }, 500); }); } getUserData();

🎉 Async Challenge!

Create a program that:

  1. Simulates fetching user data (use setTimeout)
  2. Chains multiple async operations
  3. Handles errors properly
  4. Uses both promises and async/await

🛡️ Module 12: Error Handling

Making your code robust and reliable

🚨 Understanding Errors

Think of error handling like having a spare tire in your car.

You hope you never need it, but when you get a flat tire, you're glad you have it. Error handling ensures your program can recover gracefully from unexpected situations.

// Different types of errors try { // ReferenceError: variable doesn't exist console.log(undefinedVariable); // TypeError: wrong type of operation let num = 5; num.toUpperCase(); // SyntaxError: invalid syntax (caught at parse time) // console.log("Unclosed string); } catch (error) { console.log("Error caught:", error.message); console.log("Error type:", error.name); }

🛟 Try/Catch/Finally

// Basic try/catch function divideNumbers(a, b) { try { if (b === 0) { throw new Error("Division by zero!"); } return a / b; } catch (error) { console.error("Error:", error.message); return null; } } console.log(divideNumbers(10, 2)); // 5 console.log(divideNumbers(10, 0)); // Error: Division by zero! // Try/catch/finally function processData(data) { try { console.log("Processing:", data); // Simulate processing if (!data) { throw new Error("No data provided"); } return data.toUpperCase(); } catch (error) { console.error("Processing failed:", error.message); return "ERROR"; } finally { console.log("Cleanup completed"); // This always runs, even if there's an error } } processData("hello"); // Processing: hello, Cleanup completed processData(null); // Processing: null, Processing failed: ..., Cleanup completed

🎯 Custom Error Types

// Custom error classes class ValidationError extends Error { constructor(message, field) { super(message); this.name = "ValidationError"; this.field = field; } } class NetworkError extends Error { constructor(message, statusCode) { super(message); this.name = "NetworkError"; this.statusCode = statusCode; } } // Using custom errors function validateUser(user) { if (!user.name) { throw new ValidationError("Name is required", "name"); } if (!user.email) { throw new ValidationError("Email is required", "email"); } if (user.age < 18) { throw new ValidationError("Must be 18 or older", "age"); } } function saveUser(user) { try { validateUser(user); // Simulate saving to database console.log("User saved successfully"); } catch (error) { if (error instanceof ValidationError) { console.log(`Validation error in ${error.field}: ${error.message}`); } else { console.log("Unexpected error:", error.message); } } } saveUser({ name: "John", email: "", age: 25 }); // Validation error saveUser({ name: "", email: "john@example.com", age: 16 }); // Validation error

⚡ Async Error Handling

// Error handling with promises function fetchUserData(userId) { return new Promise((resolve, reject) => { setTimeout(() => { if (userId <= 0) { reject(new Error("Invalid user ID")); return; } if (userId > 1000) { reject(new NetworkError("User not found", 404)); return; } resolve({ id: userId, name: "User " + userId }); }, 1000); }); } // Handling promise errors fetchUserData(123) .then(user => console.log("User:", user)) .catch(error => { if (error instanceof NetworkError) { console.log(`Network error ${error.statusCode}: ${error.message}`); } else { console.log("Error:", error.message); } }); // Async/await error handling async function getUserProfile(userId) { try { const user = await fetchUserData(userId); console.log("Profile for:", user.name); return user; } catch (error) { console.error("Failed to get user profile:", error.message); throw error; // Re-throw to let caller handle it } } // Using with try/catch async function displayUser(userId) { try { const user = await getUserProfile(userId); console.log("Displaying user:", user); } catch (error) { console.log("Could not display user:", error.message); } } displayUser(123); // Success displayUser(-1); // Error

🎉 Error Handling Challenge!

Create robust error handling for:

  1. A calculator function with input validation
  2. An async API call with retry logic
  3. Custom error types for different scenarios
  4. Graceful degradation when errors occur

🚀 Ready for Projects?

Now that you know intermediate JavaScript, let's build real applications!

Go to JavaScript Projects Course →