# JavaScript Intermediate Concepts: Building on Your Foundation

Great job mastering the basics! Now that you understand variables, functions, arrays, objects, and basic operations, let's dive deeper into more powerful JavaScript concepts that will make your code more efficient and professional.

## 1. Modern Variable Declarations

While `let` and `const` are great, there are some important distinctions to understand:

### Block Scope with Let
```javascript
function example() {
    if (true) {
        let blockScoped = "I'm only available here";
        var functionScoped = "I'm available everywhere in this function";
    }
    
    // console.log(blockScoped); // This would throw an error!
    console.log(functionScoped); // Works fine
}
```

### Const with Objects and Arrays
```javascript
const person = {
    name: "John",
    age: 30
};

// You can modify properties, but not reassign the variable
person.name = "Jane";        // This works!
person.age = 25;             // This also works!
// person = {};               // This would throw an error!

const numbers = [1, 2, 3];
numbers.push(4);            // This works!
// numbers = [5, 6, 7];      // This throws an error
```

## 2. Advanced Functions

### Arrow Functions (ES6+)
```javascript
// Traditional function
function add(a, b) {
    return a + b;
}

// Arrow function - shorter syntax
const addArrow = (a, b) => a + b;

// More examples
const greet = name => `Hello, ${name}!`;
const square = x => x * x;
const multiply = (a, b) => { return a * b; }; // With explicit return
```

### Default Parameters
```javascript
function createGreeting(name, greeting = "Hello") {
    return `${greeting}, ${name}!`;
}

console.log(createGreeting("John"));           // Hello, John!
console.log(createGreeting("Jane", "Hi"));     // Hi, Jane!
```

## 3. Enhanced Object Syntax (ES6+)

### Property Shorthand
```javascript
const name = "John";
const age = 30;

// Instead of: {name: name, age: age}
const person = {
    name,
    age,
    greet() {
        return `Hello, I'm ${this.name}`;
    }
};
```

### Object Methods and This
```javascript
const calculator = {
    add(a, b) {
        return a + b;
    },
    
    multiply(a, b) {
        return a * b;
    },
    
    calculate(operation, x, y) {
        // Using this to refer to the object itself
        return this[operation](x, y);
    }
};

console.log(calculator.calculate("add", 5, 3));     // 8
console.log(calculator.calculate("multiply", 4, 2)); // 8
```

## 4. Array Methods (Higher-Order Functions)

These are powerful tools for working with arrays:

### forEach - Loop without return value
```javascript
const fruits = ["apple", "banana", "orange"];

fruits.forEach((fruit, index) => {
    console.log(`${index}: ${fruit}`);
});
// Output:
// 0: apple
// 1: banana
// 2: orange
```

### map - Transform array elements
```javascript
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// Transform objects
const users = [
    {name: "John", age: 30},
    {name: "Jane", age: 25}
];

const userNames = users.map(user => user.name);
console.log(userNames); // ["John", "Jane"]
```

### filter - Create new array with filtered items
```javascript
const ages = [18, 25, 30, 16, 22];
const adults = ages.filter(age => age >= 18);
console.log(adults); // [18, 25, 30, 22]
```

### find - Get first matching item
```javascript
const products = [
    {id: 1, name: "Laptop", price: 999},
    {id: 2, name: "Phone", price: 599}
];

const laptop = products.find(product => product.name === "Laptop");
console.log(laptop); // {id: 1, name: "Laptop", price: 999}
```

### reduce - Accumulate values
```javascript
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((total, current) => total + current, 0);
console.log(sum); // 15

// Find most expensive product
const maxPrice = products.reduce((max, product) => 
    product.price > max ? product.price : max, 0
);
```

## 5. String Methods and Template Literals

### Template Literals (ES6+)
```javascript
const name = "John";
const age = 30;

// Instead of: "Hello, my name is " + name + " and I am " + age + " years old"
const message = `Hello, my name is ${name} and I am ${age} years old`;

const multiline = `
This is a
multiline string
with variables like ${name}
`;
```

### Useful String Methods
```javascript
const text = "JavaScript is awesome";

console.log(text.toUpperCase());      // JAVASCRIPT IS AWESOME
console.log(text.toLowerCase());      // javascript is awesome
console.log(text.slice(0, 10));       // JavaScript
console.log(text.includes("awesome")); // true
console.log(text.split(" "));         // ["JavaScript", "is", "awesome"]
```

## 6. Working with Dates

```javascript
// Current date and time
const now = new Date();
console.log(now); // Thu Dec 07 2023 14:30:45 GMT-0500 (EST)

// Get specific parts
console.log(now.getFullYear());   // 2023
console.log(now.getMonth());      // 11 (December, months start at 0)
console.log(now.getDate());       // 7

// Create custom date
const birthday = new Date("2023-12-25");
```

## 7. Error Handling with Try-Catch

```javascript
function divide(a, b) {
    try {
        if (b === 0) {
            throw new Error("Cannot divide by zero!");
        }
        return a / b;
    } catch (error) {
        console.log("Error:", error.message);
        return null;
    }
}

console.log(divide(10, 2)); // 5
console.log(divide(10, 0)); // Error: Cannot divide by zero!
```

## 8. Scope and Closures

```javascript
function outerFunction(x) {
    const outerVariable = "I'm from outer function";
    
    return function innerFunction(y) {
        console.log(`x: ${x}, y: ${y}`);
        console.log(outerVariable); // Can access outer scope!
        return x + y;
    };
}

const myClosure = outerFunction(10);
console.log(myClosure(5)); // x: 10, y: 5 → 15
```

## 9. Asynchronous JavaScript (Basics)

### Promises and Async/Await

```javascript
// Simple promise example
function fetchUserData(userId) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (userId > 0) {
                resolve({id: userId, name: "User" + userId});
            } else {
                reject("Invalid user ID");
            }
        }, 1000);
    });
}

// Using async/await
async function getUserInfo() {
    try {
        const user = await fetchUserData(123);
        console.log(user); // {id: 123, name: "User123"}
    } catch (error) {
        console.log(error);
    }
}
```

## 10. Practical Examples

### Simple Calculator
```javascript
class Calculator {
    add(a, b) { return a + b; }
    subtract(a, b) { return a - b; }
    multiply(a, b) { return a * b; }
    
    calculate(operation, x, y) {
        switch (operation) {
            case "add": return this.add(x, y);
            case "subtract": return this.subtract(x, y);
            case "multiply": return this.multiply(x, y);
            default: return null;
        }
    }
}

const calc = new Calculator();
console.log(calc.calculate("add", 5, 3)); // 8
```

### Todo List Manager
```javascript
class TodoManager {
    constructor() {
        this.todos = [];
    }
    
    addTodo(text) {
        const todo = {
            id: Date.now(),
            text,
            completed: false
        };
        this.todos.push(todo);
    }
    
    removeTodo(id) {
        this.todos = this.todos.filter(todo => todo.id !== id);
    }
    
    toggleComplete(id) {
        const todo = this.todos.find(t => t.id === id);
        if (todo) {
            todo.completed = !todo.completed;
        }
    }
}
```

## What's Next?

You're now ready to tackle more advanced topics like:
- DOM manipulation for interactive web pages
- Working with APIs and fetching data from the internet
- Event handling and user interactions
- More complex object-oriented programming concepts
- Modern JavaScript frameworks like React or Vue

Keep practicing by building small projects that combine these new concepts. The more you code, the more natural these patterns will become!