The Complete JavaScript Guide

    Table of Contents

    1. Introduction to JavaScript
    2. Setting Up Your Development Environment
    3. JavaScript Fundamentals
    4. Variables and Data Types
    5. Operators
    6. Control Structures
    7. Functions
    8. Objects and Arrays
    9. DOM Manipulation
    10. Events
    11. Asynchronous JavaScript
    12. ES6+ Features
    13. Error Handling
    14. Modules
    15. Advanced Concepts
    16. JavaScript Frameworks Overview
    17. Best Practices
    18. Testing
    19. Performance Optimization
    20. Project Examples

    1. Introduction to JavaScript {#introduction}

    JavaScript is a versatile, high-level programming language that powers the modern web. Originally created for client-side scripting, it has evolved into a full-stack development language.

    graph TD
        A[JavaScript] --> B[Client-Side]
        A --> C[Server-Side]
        A --> D[Mobile Apps]
        A --> E[Desktop Apps]
    
        B --> F[DOM Manipulation]
        B --> G[User Interactions]
        B --> H[Animations]
    
        C --> I[Node.js]
        C --> J[APIs]
        C --> K[Databases]
    
        D --> L[React Native]
        D --> M[Ionic]
    
        E --> N[Electron]

    JavaScript’s Role in Web Development

    flowchart LR
        A[HTML] --> D[Complete Web Application]
        B[CSS] --> D
        C[JavaScript] --> D
    
        A -.-> E[Structure]
        B -.-> F[Styling]
        C -.-> G[Behavior & Logic]

    2. Setting Up Your Development Environment {#setup}

    Tools You’ll Need

    1. Code Editor: Visual Studio Code (recommended)
    2. Web Browser: Chrome, Firefox, or Edge with Developer Tools
    3. Node.js: For server-side development and package management

    Browser Developer Tools

    graph TD
        A[Browser Dev Tools] --> B[Console]
        A --> C[Elements]
        A --> D[Network]
        A --> E[Sources]
        A --> F[Application]
    
        B --> G[Error Messages]
        B --> H[Code Testing]
    
        C --> I[HTML Structure]
        C --> J[CSS Styles]
    
        D --> K[HTTP Requests]
        D --> L[Performance]

    3. JavaScript Fundamentals {#fundamentals}

    How JavaScript Works

    sequenceDiagram
        participant Browser
        participant JS_Engine
        participant Memory
        participant Call_Stack
    
        Browser->>JS_Engine: Load JavaScript Code
        JS_Engine->>Memory: Allocate Variables
        JS_Engine->>Call_Stack: Execute Functions
        Call_Stack->>Memory: Access Variables
        Call_Stack->>Browser: Update DOM

    JavaScript Execution Context

    graph TD
        A[Global Execution Context] --> B[Creation Phase]
        A --> C[Execution Phase]
    
        B --> D[Hoisting]
        B --> E[Variable Environment]
        B --> F[Scope Chain]
    
        C --> G[Code Execution]
        C --> H[Function Calls]
    
        H --> I[Function Execution Context]

    4. Variables and Data Types {#variables}

    Variable Declarations

    // var (function-scoped, hoisted)
    var name = "John";
    
    // let (block-scoped, not hoisted)
    let age = 25;
    
    // const (block-scoped, immutable reference)
    const PI = 3.14159;
    JavaScript

    Data Types Hierarchy

    graph TD
        A[JavaScript Data Types] --> B[Primitive Types]
        A --> C[Non-Primitive Types]
    
        B --> D[Number]
        B --> E[String]
        B --> F[Boolean]
        B --> G[Undefined]
        B --> H[Null]
        B --> I[Symbol]
        B --> J[BigInt]
    
        C --> K[Object]
        C --> L[Array]
        C --> M[Function]
        C --> N[Date]
        C --> O[RegExp]

    Type Conversion Flow

    flowchart LR
        A[Input Value] --> B{Type Check}
        B -->|String| C[String Operations]
        B -->|Number| D[Numeric Operations]
        B -->|Boolean| E[Logical Operations]
        B -->|Object| F[Object Operations]
    
        C --> G[Implicit Conversion]
        D --> G
        E --> G
        F --> G
    
        G --> H[Result]

    Examples

    // Numbers
    let integer = 42;
    let decimal = 3.14;
    let scientific = 2e10;
    
    // Strings
    let singleQuotes = 'Hello';
    let doubleQuotes = "World";
    let templateLiteral = `Hello, ${name}!`;
    
    // Booleans
    let isTrue = true;
    let isFalse = false;
    
    // Arrays
    let fruits = ['apple', 'banana', 'orange'];
    
    // Objects
    let person = {
        name: 'Alice',
        age: 30,
        city: 'New York'
    };
    JavaScript

    5. Operators {#operators}

    Operator Precedence

    graph TD
        A["Operator Precedence"] --> B["Highest: () [] ."]
        B --> C["Unary: ! ++ --"]
        C --> D["Multiplicative: * / %"]
        D --> E["Additive: + -"]
        E --> F["Relational: < > <= >="]
        F --> G["Equality: == != === !=="]
        G --> H["Logical AND: &&"]
        H --> I["Logical OR: ||"]
        I --> J["Assignment: ="]

    Comparison Operators

    // Equality vs Strict Equality
    console.log(5 == "5");   // true (type coercion)
    console.log(5 === "5");  // false (no type coercion)
    
    // Comparison
    console.log(10 > 5);     // true
    console.log(10 <= 10);   // true
    JavaScript

    6. Control Structures {#control-structures}

    Conditional Flow

    flowchart TD
        A[Start] --> B{Condition}
        B -->|True| C[Execute If Block]
        B -->|False| D{Else If?}
        D -->|True| E[Execute Else If Block]
        D -->|False| F[Execute Else Block]
        C --> G[End]
        E --> G
        F --> G

    Loop Types

    graph LR
        A[JavaScript Loops] --> B[for]
        A --> C[while]
        A --> D[do-while]
        A --> E[for...in]
        A --> F[for...of]
    
        B --> G[Counter-based]
        C --> H[Condition-based]
        D --> I[Execute at least once]
        E --> J[Object properties]
        F --> K[Iterable values]

    Examples

    // If-else statement
    if (age >= 18) {
        console.log("You are an adult");
    } else if (age >= 13) {
        console.log("You are a teenager");
    } else {
        console.log("You are a child");
    }
    
    // Switch statement
    switch (day) {
        case "Monday":
            console.log("Start of the work week");
            break;
        case "Friday":
            console.log("TGIF!");
            break;
        default:
            console.log("Regular day");
    }
    
    // For loop
    for (let i = 0; i < 5; i++) {
        console.log(`Iteration ${i}`);
    }
    
    // While loop
    let count = 0;
    while (count < 3) {
        console.log(`Count: ${count}`);
        count++;
    }
    
    // For...of loop (arrays)
    for (const fruit of fruits) {
        console.log(fruit);
    }
    
    // For...in loop (objects)
    for (const key in person) {
        console.log(`${key}: ${person[key]}`);
    }
    JavaScript

    7. Functions {#functions}

    Function Types and Scope

    graph TD
        A[JavaScript Functions] --> B[Function Declaration]
        A --> C[Function Expression]
        A --> D[Arrow Function]
        A --> E[Anonymous Function]
        A --> F[IIFE]
    
        G[Function Scope] --> H[Global Scope]
        G --> I[Function Scope]
        G --> J[Block Scope]
    
        H --> K[Accessible everywhere]
        I --> L[Accessible within function]
        J --> M[Accessible within block]

    Function Execution Flow

    sequenceDiagram
        participant Caller
        participant Function
        participant Local_Scope
        participant Return
    
        Caller->>Function: Call with arguments
        Function->>Local_Scope: Create execution context
        Local_Scope->>Local_Scope: Execute function body
        Local_Scope->>Return: Calculate return value
        Return->>Caller: Return result

    Examples

    // Function Declaration
    function greet(name) {
        return `Hello, ${name}!`;
    }
    
    // Function Expression
    const add = function(a, b) {
        return a + b;
    };
    
    // Arrow Function
    const multiply = (a, b) => a * b;
    
    // Arrow function with multiple statements
    const processData = (data) => {
        const processed = data.map(item => item * 2);
        return processed.filter(item => item > 10);
    };
    
    // Default Parameters
    function createUser(name, age = 18, city = "Unknown") {
        return { name, age, city };
    }
    
    // Rest Parameters
    function sum(...numbers) {
        return numbers.reduce((total, num) => total + num, 0);
    }
    
    // Higher-Order Functions
    function withLogging(fn) {
        return function(...args) {
            console.log(`Calling function with args: ${args}`);
            const result = fn(...args);
            console.log(`Result: ${result}`);
            return result;
        };
    }
    
    const loggedAdd = withLogging(add);
    JavaScript

    8. Objects and Arrays {#objects-arrays}

    Object Structure and Methods

    graph TD
        A[JavaScript Object] --> B[Properties]
        A --> C[Methods]
        A --> D[Prototype]
    
        B --> E[Primitive Values]
        B --> F[Object References]
    
        C --> G[Function Properties]
    
        D --> H[Inherited Properties]
        D --> I[Inherited Methods]

    Array Methods Categories

    mindmap
      root((Array Methods))
        Mutating
          push
          pop
          shift
          unshift
          splice
          sort
          reverse
        Non-Mutating
          map
          filter
          reduce
          find
          indexOf
          slice
          concat
        Iteration
          forEach
          every
          some
          includes

    Examples

    // Object Creation and Manipulation
    const car = {
        brand: "Toyota",
        model: "Camry",
        year: 2023,
        start() {
            console.log("Engine started");
        }
    };
    
    // Object destructuring
    const { brand, model } = car;
    
    // Object.keys, Object.values, Object.entries
    console.log(Object.keys(car));
    console.log(Object.values(car));
    console.log(Object.entries(car));
    
    // Array Methods
    const numbers = [1, 2, 3, 4, 5];
    
    // Map - transform each element
    const doubled = numbers.map(num => num * 2);
    
    // Filter - select elements based on condition
    const evens = numbers.filter(num => num % 2 === 0);
    
    // Reduce - accumulate values
    const sum = numbers.reduce((acc, num) => acc + num, 0);
    
    // Find - get first matching element
    const found = numbers.find(num => num > 3);
    
    // Array destructuring
    const [first, second, ...rest] = numbers;
    
    // Spread operator
    const newArray = [...numbers, 6, 7, 8];
    const combinedArrays = [...numbers, ...doubled];
    JavaScript

    9. DOM Manipulation {#dom}

    DOM Tree Structure

    graph TD
        A[Document] --> B[HTML]
        B --> C[Head]
        B --> D[Body]
    
        C --> E[Title]
        C --> F[Meta]
        C --> G[Link]
    
        D --> H[Header]
        D --> I[Main]
        D --> J[Footer]
    
        I --> K[Section]
        I --> L[Article]
    
        K --> M[H2]
        K --> N[P]
        K --> O[Div]

    DOM Manipulation Flow

    flowchart LR
        A[Select Element] --> B[Modify Element]
        B --> C[Update DOM]
        C --> D[Browser Re-render]
    
        A --> E[getElementById]
        A --> F[querySelector]
        A --> G[getElementsByClass]
    
        B --> H[Change Content]
        B --> I[Modify Attributes]
        B --> J[Update Styles]
        B --> K[Add/Remove Classes]

    Examples

    // Selecting Elements
    const title = document.getElementById('title');
    const buttons = document.querySelectorAll('.btn');
    const firstParagraph = document.querySelector('p');
    
    // Creating Elements
    const newDiv = document.createElement('div');
    newDiv.textContent = 'Hello World';
    newDiv.className = 'highlight';
    
    // Modifying Content
    title.textContent = 'New Title';
    title.innerHTML = '<span>Formatted Title</span>';
    
    // Modifying Attributes
    const image = document.querySelector('img');
    image.src = 'new-image.jpg';
    image.alt = 'New Image Description';
    
    // Modifying Styles
    title.style.color = 'blue';
    title.style.fontSize = '24px';
    
    // Adding/Removing Classes
    title.classList.add('active');
    title.classList.remove('inactive');
    title.classList.toggle('highlighted');
    
    // Adding Elements to DOM
    document.body.appendChild(newDiv);
    title.insertAdjacentElement('afterend', newDiv);
    
    // Removing Elements
    const oldElement = document.querySelector('.old');
    oldElement.remove();
    JavaScript

    10. Events {#events}

    Event Flow

    sequenceDiagram
        participant User
        participant Browser
        participant Document
        participant Target_Element
        participant Event_Handler
    
        User->>Browser: Performs Action (click, keypress, etc.)
        Browser->>Document: Create Event Object
        Document->>Target_Element: Event Capturing Phase
        Target_Element->>Target_Element: Event Target Phase
        Target_Element->>Document: Event Bubbling Phase
        Target_Element->>Event_Handler: Execute Event Handler

    Event Types

    mindmap
      root((JavaScript Events))
        Mouse Events
          click
          dblclick
          mousedown
          mouseup
          mouseover
          mouseout
        Keyboard Events
          keydown
          keyup
          keypress
        Form Events
          submit
          change
          input
          focus
          blur
        Window Events
          load
          resize
          scroll
          unload

    Examples

    // Basic Event Listener
    const button = document.querySelector('#myButton');
    
    button.addEventListener('click', function(event) {
        console.log('Button clicked!');
        console.log('Event target:', event.target);
    });
    
    // Arrow function event handler
    button.addEventListener('click', (e) => {
        e.preventDefault(); // Prevent default behavior
        console.log('Arrow function handler');
    });
    
    // Multiple event types
    const input = document.querySelector('#myInput');
    
    input.addEventListener('focus', () => {
        input.style.backgroundColor = 'lightblue';
    });
    
    input.addEventListener('blur', () => {
        input.style.backgroundColor = 'white';
    });
    
    input.addEventListener('input', (e) => {
        console.log('Current value:', e.target.value);
    });
    
    // Event Delegation
    document.addEventListener('click', (e) => {
        if (e.target.classList.contains('delete-btn')) {
            e.target.parentElement.remove();
        }
    });
    
    // Custom Events
    const customEvent = new CustomEvent('userLoggedIn', {
        detail: { username: 'john_doe', timestamp: Date.now() }
    });
    
    document.addEventListener('userLoggedIn', (e) => {
        console.log(`User ${e.detail.username} logged in at ${e.detail.timestamp}`);
    });
    
    document.dispatchEvent(customEvent);
    JavaScript

    11. Asynchronous JavaScript {#async}

    Asynchronous Programming Evolution

    graph LR
        A[Callbacks] --> B[Promises]
        B --> C[Async/Await]
    
        A --> D[Callback Hell]
        B --> E[Promise Chaining]
        C --> F[Synchronous-like Code]
    
        D --> G[Hard to Read]
        E --> H[Better Error Handling]
        F --> I[Clean & Maintainable]

    Promise States

    stateDiagram-v2
        [*] --> Pending
        Pending --> Fulfilled: resolve()
        Pending --> Rejected: reject()
        Fulfilled --> [*]
        Rejected --> [*]
    
        note right of Fulfilled: .then() handler
        note right of Rejected: .catch() handler

    Async/Await Flow

    sequenceDiagram
        participant Function
        participant Promise
        participant Event_Loop
        participant Result
    
        Function->>Promise: await someAsyncOperation()
        Promise->>Event_Loop: Suspend function execution
        Event_Loop->>Event_Loop: Continue other tasks
        Event_Loop->>Promise: Async operation completes
        Promise->>Function: Resume with result/error
        Function->>Result: Continue execution

    Examples

    // Callbacks (older approach)
    function fetchUserData(userId, callback) {
        setTimeout(() => {
            const userData = { id: userId, name: "John Doe" };
            callback(null, userData);
        }, 1000);
    }
    
    // Callback usage
    fetchUserData(123, (error, data) => {
        if (error) {
            console.error('Error:', error);
        } else {
            console.log('User data:', data);
        }
    });
    
    // Promises
    function fetchUserDataPromise(userId) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (userId > 0) {
                    const userData = { id: userId, name: "John Doe" };
                    resolve(userData);
                } else {
                    reject(new Error('Invalid user ID'));
                }
            }, 1000);
        });
    }
    
    // Promise usage
    fetchUserDataPromise(123)
        .then(data => {
            console.log('User data:', data);
            return fetchUserDataPromise(456); // Chain another promise
        })
        .then(data => {
            console.log('Second user:', data);
        })
        .catch(error => {
            console.error('Error:', error);
        })
        .finally(() => {
            console.log('Operation completed');
        });
    
    // Async/Await
    async function getUserData(userId) {
        try {
            const userData = await fetchUserDataPromise(userId);
            console.log('User data:', userData);
    
            const secondUser = await fetchUserDataPromise(456);
            console.log('Second user:', secondUser);
    
            return userData;
        } catch (error) {
            console.error('Error:', error);
            throw error;
        }
    }
    
    // Fetch API
    async function fetchFromAPI() {
        try {
            const response = await fetch('https://jsonplaceholder.typicode.com/users');
    
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
    
            const users = await response.json();
            console.log('Users:', users);
            return users;
        } catch (error) {
            console.error('Fetch error:', error);
        }
    }
    
    // Promise.all - Wait for multiple promises
    async function fetchMultipleUsers() {
        try {
            const promises = [
                fetchUserDataPromise(1),
                fetchUserDataPromise(2),
                fetchUserDataPromise(3)
            ];
    
            const users = await Promise.all(promises);
            console.log('All users:', users);
        } catch (error) {
            console.error('One or more requests failed:', error);
        }
    }
    
    // Promise.race - First resolved promise wins
    async function fetchWithTimeout() {
        const timeoutPromise = new Promise((_, reject) => {
            setTimeout(() => reject(new Error('Timeout')), 5000);
        });
    
        try {
            const result = await Promise.race([
                fetchUserDataPromise(123),
                timeoutPromise
            ]);
            console.log('Result:', result);
        } catch (error) {
            console.error('Error or timeout:', error);
        }
    }
    JavaScript

    12. ES6+ Features {#es6}

    ES6+ Features Timeline

    timeline
        title JavaScript ES6+ Features
    
        ES6 (2015) : Arrow Functions
                    : Classes
                    : Template Literals
                    : Destructuring
                    : Modules
                    : Promises
    
        ES2017 : Async/Await
                : Object.entries()
                : String padding
    
        ES2018 : Rest/Spread for Objects
                : Promise.finally()
                : Async Iteration
    
        ES2019 : Array.flat()
                : Object.fromEntries()
                : Optional catch binding
    
        ES2020 : Optional Chaining
                : Nullish Coalescing
                : BigInt
                : Promise.allSettled()
    
        ES2021 : Logical Assignment
                : Promise.any()
                : WeakRefs

    Module System

    graph TD
        A[Module System] --> B[Export]
        A --> C[Import]
    
        B --> D[Named Export]
        B --> E[Default Export]
        B --> F["Re-export"]
    
        C --> G[Named Import]
        C --> H[Default Import]
        C --> I[Namespace Import]
    
        D --> J["export const foo = 'bar'"]
        E --> K["export default function"]
        F --> L["export { foo } from './module'"]
    
        G --> M["import { foo } from './module'"]
        H --> N["import MyFunc from './module'"]
        I --> O["import * as Utils from './module'"]

    Examples

    // Template Literals
    const name = "Alice";
    const age = 30;
    const message = `Hello, my name is ${name} and I'm ${age} years old.
    This is a multi-line string.`;
    
    // Destructuring Assignment
    const person = { name: "Bob", age: 25, city: "New York" };
    const { name: personName, age: personAge } = person;
    
    const numbers = [1, 2, 3, 4, 5];
    const [first, second, ...rest] = numbers;
    
    // Arrow Functions
    const add = (a, b) => a + b;
    const square = x => x * x;
    const greet = () => "Hello!";
    
    // Classes
    class Animal {
        constructor(name, species) {
            this.name = name;
            this.species = species;
        }
    
        speak() {
            console.log(`${this.name} makes a sound`);
        }
    
        static getSpeciesCount() {
            return Animal.count || 0;
        }
    }
    
    class Dog extends Animal {
        constructor(name, breed) {
            super(name, "Canine");
            this.breed = breed;
        }
    
        speak() {
            console.log(`${this.name} barks`);
        }
    
        fetch() {
            console.log(`${this.name} fetches the ball`);
        }
    }
    
    // Default Parameters
    function createUser(name, role = "user", active = true) {
        return { name, role, active };
    }
    
    // Rest Parameters and Spread Operator
    function logAll(...args) {
        console.log(args);
    }
    
    const arr1 = [1, 2, 3];
    const arr2 = [4, 5, 6];
    const combined = [...arr1, ...arr2];
    
    // Object Spread
    const baseConfig = { host: "localhost", port: 3000 };
    const devConfig = { ...baseConfig, debug: true };
    
    // Optional Chaining (ES2020)
    const user = {
        profile: {
            social: {
                twitter: "@username"
            }
        }
    };
    
    const twitterHandle = user?.profile?.social?.twitter;
    const nonExistent = user?.profile?.social?.instagram?.handle;
    
    // Nullish Coalescing (ES2020)
    const username = user.username ?? "Anonymous";
    const port = process.env.PORT ?? 3000;
    
    // Modules (math.js)
    export const PI = 3.14159;
    export function add(a, b) {
        return a + b;
    }
    
    export default function multiply(a, b) {
        return a * b;
    }
    
    // Using modules (main.js)
    import multiply, { PI, add } from './math.js';
    import * as MathUtils from './math.js';
    
    // Map and Set
    const userMap = new Map();
    userMap.set('john', { age: 30, email: 'john@example.com' });
    userMap.set('jane', { age: 25, email: 'jane@example.com' });
    
    const uniqueNumbers = new Set([1, 2, 3, 3, 4, 4, 5]);
    console.log(uniqueNumbers); // Set {1, 2, 3, 4, 5}
    
    // WeakMap and WeakSet (garbage collection friendly)
    const weakMap = new WeakMap();
    const obj = {};
    weakMap.set(obj, "some data");
    
    // Symbols
    const sym1 = Symbol('description');
    const sym2 = Symbol('description');
    console.log(sym1 === sym2); // false - symbols are always unique
    
    // Generators
    function* numberGenerator() {
        let num = 1;
        while (true) {
            yield num++;
        }
    }
    
    const gen = numberGenerator();
    console.log(gen.next().value); // 1
    console.log(gen.next().value); // 2
    JavaScript

    13. Error Handling {#error-handling}

    Error Handling Flow

    flowchart TD
        A[Code Execution] --> B{Error Occurs?}
        B -->|No| C[Continue Execution]
        B -->|Yes| D[Throw Error]
    
        D --> E{Try-Catch Block?}
        E -->|Yes| F[Catch Block]
        E -->|No| G[Unhandled Error]
    
        F --> H[Handle Error]
        F --> I[Finally Block]
    
        G --> J[Program Crash]
    
        H --> I
        I --> K[Continue/End]

    Error Types

    graph TD
        A[JavaScript Errors] --> B[Syntax Errors]
        A --> C[Runtime Errors]
        A --> D[Logical Errors]
    
        B --> E[SyntaxError]
    
        C --> F[TypeError]
        C --> G[ReferenceError]
        C --> H[RangeError]
        C --> I[Custom Errors]
    
        D --> J[Code works but produces wrong results]

    Examples

    // Basic Try-Catch
    try {
        const result = riskyOperation();
        console.log('Success:', result);
    } catch (error) {
        console.error('Error occurred:', error.message);
    } finally {
        console.log('This always runs');
    }
    
    // Custom Error Classes
    class ValidationError extends Error {
        constructor(message, field) {
            super(message);
            this.name = 'ValidationError';
            this.field = field;
        }
    }
    
    class NetworkError extends Error {
        constructor(message, status) {
            super(message);
            this.name = 'NetworkError';
            this.status = status;
        }
    }
    
    // Function that throws custom errors
    function validateUser(user) {
        if (!user.name) {
            throw new ValidationError('Name is required', 'name');
        }
    
        if (!user.email || !user.email.includes('@')) {
            throw new ValidationError('Valid email is required', 'email');
        }
    
        if (user.age < 0 || user.age > 150) {
            throw new ValidationError('Age must be between 0 and 150', 'age');
        }
    
        return true;
    }
    
    // Error Handling with Async/Await
    async function fetchUserData(userId) {
        try {
            const response = await fetch(`/api/users/${userId}`);
    
            if (!response.ok) {
                throw new NetworkError(
                    `Failed to fetch user: ${response.statusText}`,
                    response.status
                );
            }
    
            const userData = await response.json();
            validateUser(userData);
    
            return userData;
        } catch (error) {
            if (error instanceof ValidationError) {
                console.error(`Validation error in ${error.field}: ${error.message}`);
            } else if (error instanceof NetworkError) {
                console.error(`Network error (${error.status}): ${error.message}`);
            } else {
                console.error('Unexpected error:', error);
            }
    
            throw error; // Re-throw for caller to handle
        }
    }
    
    // Promise Error Handling
    fetchUserData(123)
        .then(user => {
            console.log('User loaded:', user);
        })
        .catch(error => {
            console.error('Failed to load user:', error.message);
        });
    
    // Global Error Handling
    window.addEventListener('error', (event) => {
        console.error('Global error:', event.error);
        // Log to error tracking service
    });
    
    window.addEventListener('unhandledrejection', (event) => {
        console.error('Unhandled promise rejection:', event.reason);
        event.preventDefault(); // Prevent default behavior
    });
    
    // Error Boundaries for Specific Operations
    function withErrorHandling(operation) {
        return async function(...args) {
            try {
                return await operation(...args);
            } catch (error) {
                console.error(`Error in ${operation.name}:`, error);
    
                // Log to monitoring service
                logError(error, operation.name, args);
    
                // Return default value or rethrow
                throw error;
            }
        };
    }
    
    // Usage
    const safeUserFetch = withErrorHandling(fetchUserData);
    
    // Defensive Programming
    function safeDivision(a, b) {
        if (typeof a !== 'number' || typeof b !== 'number') {
            throw new TypeError('Both arguments must be numbers');
        }
    
        if (b === 0) {
            throw new RangeError('Division by zero is not allowed');
        }
    
        return a / b;
    }
    
    // Input Validation
    function processUserInput(input) {
        // Sanitize input
        const sanitized = input?.toString().trim();
    
        if (!sanitized) {
            throw new ValidationError('Input cannot be empty');
        }
    
        if (sanitized.length > 100) {
            throw new ValidationError('Input too long (max 100 characters)');
        }
    
        return sanitized;
    }
    JavaScript

    14. Modules {#modules}

    Module Loading Process

    sequenceDiagram
        participant Browser
        participant Module_Loader
        participant Module_A
        participant Module_B
        participant Module_C
    
        Browser->>Module_Loader: Load main.js
        Module_Loader->>Module_A: Import moduleA
        Module_A->>Module_B: Import moduleB
        Module_B->>Module_C: Import moduleC
        Module_C->>Module_B: Export complete
        Module_B->>Module_A: Export complete
        Module_A->>Module_Loader: Export complete
        Module_Loader->>Browser: All modules loaded

    Module Patterns

    graph TD
        A[Module Patterns] --> B[ES6 Modules]
        A --> C[CommonJS]
        A --> D[AMD]
        A --> E[UMD]
        A --> F[IIFE]
    
        B --> G[import/export]
        C --> H[require/module.exports]
        D --> I[define/require]
        E --> J[Universal Module]
        F --> K[Immediately Invoked]

    Examples

    // ES6 Modules
    
    // utils.js - Named exports
    export const PI = 3.14159;
    
    export function add(a, b) {
        return a + b;
    }
    
    export function subtract(a, b) {
        return a - b;
    }
    
    export class Calculator {
        static add(a, b) {
            return a + b;
        }
    
        static multiply(a, b) {
            return a * b;
        }
    }
    
    // math.js - Default export with named exports
    const DEFAULT_PRECISION = 2;
    
    export default class MathUtils {
        static round(number, precision = DEFAULT_PRECISION) {
            return Math.round(number * Math.pow(10, precision)) / Math.pow(10, precision);
        }
    
        static random(min = 0, max = 1) {
            return Math.random() * (max - min) + min;
        }
    }
    
    export { DEFAULT_PRECISION };
    
    // api.js - Async module
    const BASE_URL = 'https://api.example.com';
    
    export async function fetchUser(id) {
        const response = await fetch(`${BASE_URL}/users/${id}`);
        if (!response.ok) {
            throw new Error(`Failed to fetch user: ${response.statusText}`);
        }
        return response.json();
    }
    
    export async function fetchUsers() {
        const response = await fetch(`${BASE_URL}/users`);
        if (!response.ok) {
            throw new Error(`Failed to fetch users: ${response.statusText}`);
        }
        return response.json();
    }
    
    // config.js - Configuration module
    const config = {
        development: {
            apiUrl: 'http://localhost:3000/api',
            debug: true
        },
        production: {
            apiUrl: 'https://api.myapp.com',
            debug: false
        }
    };
    
    const currentEnv = process.env.NODE_ENV || 'development';
    
    export default config[currentEnv];
    
    // main.js - Importing modules
    import MathUtils, { DEFAULT_PRECISION } from './math.js';
    import { add, subtract, Calculator } from './utils.js';
    import { fetchUser, fetchUsers } from './api.js';
    import config from './config.js';
    
    // Dynamic imports
    async function loadModule() {
        const module = await import('./heavy-module.js');
        return module.default;
    }
    
    // Re-exports (barrel exports)
    // index.js
    export { add, subtract } from './utils.js';
    export { default as MathUtils } from './math.js';
    export * from './api.js';
    
    // Module with side effects
    // logger.js
    console.log('Logger module loaded');
    
    let logLevel = 'info';
    
    export function setLogLevel(level) {
        logLevel = level;
    }
    
    export function log(message, level = 'info') {
        if (shouldLog(level)) {
            console.log(`[${level.toUpperCase()}] ${message}`);
        }
    }
    
    function shouldLog(level) {
        const levels = ['debug', 'info', 'warn', 'error'];
        return levels.indexOf(level) >= levels.indexOf(logLevel);
    }
    
    // Circular dependency handling
    // moduleA.js
    import { functionB } from './moduleB.js';
    
    export function functionA() {
        console.log('Function A');
        return 'A';
    }
    
    export function callB() {
        return functionB();
    }
    
    // moduleB.js
    import { functionA } from './moduleA.js';
    
    export function functionB() {
        console.log('Function B');
        return 'B';
    }
    
    export function callA() {
        return functionA();
    }
    
    // Module factory pattern
    // createStore.js
    export default function createStore(initialState = {}) {
        let state = { ...initialState };
        const listeners = [];
    
        return {
            getState() {
                return { ...state };
            },
    
            setState(newState) {
                state = { ...state, ...newState };
                listeners.forEach(listener => listener(state));
            },
    
            subscribe(listener) {
                listeners.push(listener);
                return () => {
                    const index = listeners.indexOf(listener);
                    if (index > -1) {
                        listeners.splice(index, 1);
                    }
                };
            }
        };
    }
    
    // Usage
    import createStore from './createStore.js';
    
    const store = createStore({ count: 0 });
    
    const unsubscribe = store.subscribe((state) => {
        console.log('State changed:', state);
    });
    
    store.setState({ count: 1 });
    JavaScript

    15. Advanced Concepts {#advanced}

    JavaScript Engine Execution

    graph TD
        A[JavaScript Code] --> B[Tokenization]
        B --> C[Parsing]
        C --> D[AST Generation]
        D --> E[Compilation]
        E --> F[Execution]
    
        F --> G[Call Stack]
        F --> H[Memory Heap]
        F --> I[Event Loop]
    
        I --> J[Callback Queue]
        I --> K[Microtask Queue]
        I --> L[Render Queue]

    Prototype Chain

    graph TD
        A[Object Instance] --> B[Constructor.prototype]
        B --> C[Object.prototype]
        C --> D[null]
    
        A --> E[hasOwnProperty]
        B --> F[Constructor Methods]
        C --> G[toString, valueOf, etc.]
    
        style A fill:#e1f5fe
        style B fill:#f3e5f5
        style C fill:#fff3e0
        style D fill:#ffebee

    Closure Scope Chain

    graph LR
        A[Inner Function] --> B[Function Scope]
        B --> C[Outer Function Scope]
        C --> D[Global Scope]
    
        A -.-> E[Has access to all]
        B -.-> F[Own variables]
        C -.-> G[Outer variables]
        D -.-> H[Global variables]

    Examples

    // Closures
    function createCounter() {
        let count = 0;
    
        return {
            increment() {
                count++;
                return count;
            },
    
            decrement() {
                count--;
                return count;
            },
    
            getCount() {
                return count;
            }
        };
    }
    
    const counter1 = createCounter();
    const counter2 = createCounter();
    
    console.log(counter1.increment()); // 1
    console.log(counter1.increment()); // 2
    console.log(counter2.increment()); // 1 (separate instance)
    
    // Prototypes and Inheritance
    function Animal(name) {
        this.name = name;
    }
    
    Animal.prototype.speak = function() {
        console.log(`${this.name} makes a sound`);
    };
    
    Animal.prototype.sleep = function() {
        console.log(`${this.name} is sleeping`);
    };
    
    function Dog(name, breed) {
        Animal.call(this, name); // Call parent constructor
        this.breed = breed;
    }
    
    // Set up inheritance
    Dog.prototype = Object.create(Animal.prototype);
    Dog.prototype.constructor = Dog;
    
    // Override method
    Dog.prototype.speak = function() {
        console.log(`${this.name} barks`);
    };
    
    // Add new method
    Dog.prototype.fetch = function() {
        console.log(`${this.name} fetches the ball`);
    };
    
    const dog = new Dog("Buddy", "Golden Retriever");
    dog.speak(); // "Buddy barks"
    dog.sleep(); // "Buddy is sleeping" (inherited)
    
    // this binding
    const obj = {
        name: "Object",
    
        regularFunction() {
            console.log("Regular function this:", this.name);
    
            // Arrow function inherits this from enclosing scope
            const arrowFunction = () => {
                console.log("Arrow function this:", this.name);
            };
    
            arrowFunction();
    
            // Regular function has its own this
            function nestedFunction() {
                console.log("Nested function this:", this); // undefined in strict mode
            }
    
            nestedFunction();
        }
    };
    
    // call, apply, bind
    function greet(greeting, punctuation) {
        console.log(`${greeting}, ${this.name}${punctuation}`);
    }
    
    const person = { name: "Alice" };
    
    greet.call(person, "Hello", "!");        // "Hello, Alice!"
    greet.apply(person, ["Hi", "."]);        // "Hi, Alice."
    
    const boundGreet = greet.bind(person, "Hey");
    boundGreet("?");                         // "Hey, Alice?"
    
    // Higher-Order Functions
    function withTiming(fn) {
        return function(...args) {
            const start = performance.now();
            const result = fn.apply(this, args);
            const end = performance.now();
            console.log(`Function took ${end - start} milliseconds`);
            return result;
        };
    }
    
    function withRetry(fn, maxAttempts = 3) {
        return async function(...args) {
            let lastError;
    
            for (let attempt = 1; attempt <= maxAttempts; attempt++) {
                try {
                    return await fn.apply(this, args);
                } catch (error) {
                    lastError = error;
                    console.log(`Attempt ${attempt} failed:`, error.message);
    
                    if (attempt < maxAttempts) {
                        await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
                    }
                }
            }
    
            throw lastError;
        };
    }
    
    // Debouncing and Throttling
    function debounce(func, delay) {
        let timeoutId;
    
        return function(...args) {
            clearTimeout(timeoutId);
            timeoutId = setTimeout(() => func.apply(this, args), delay);
        };
    }
    
    function throttle(func, limit) {
        let inThrottle;
    
        return function(...args) {
            if (!inThrottle) {
                func.apply(this, args);
                inThrottle = true;
                setTimeout(() => inThrottle = false, limit);
            }
        };
    }
    
    // Event Emitter Pattern
    class EventEmitter {
        constructor() {
            this.events = {};
        }
    
        on(event, listener) {
            if (!this.events[event]) {
                this.events[event] = [];
            }
            this.events[event].push(listener);
        }
    
        off(event, listenerToRemove) {
            if (!this.events[event]) return;
    
            this.events[event] = this.events[event].filter(
                listener => listener !== listenerToRemove
            );
        }
    
        emit(event, ...args) {
            if (!this.events[event]) return;
    
            this.events[event].forEach(listener => {
                listener.apply(this, args);
            });
        }
    
        once(event, listener) {
            const oneTimeListener = (...args) => {
                listener.apply(this, args);
                this.off(event, oneTimeListener);
            };
    
            this.on(event, oneTimeListener);
        }
    }
    
    // Memoization
    function memoize(fn) {
        const cache = new Map();
    
        return function(...args) {
            const key = JSON.stringify(args);
    
            if (cache.has(key)) {
                console.log('Cache hit');
                return cache.get(key);
            }
    
            console.log('Computing result');
            const result = fn.apply(this, args);
            cache.set(key, result);
            return result;
        };
    }
    
    // Expensive function example
    const expensiveCalculation = memoize((n) => {
        let result = 0;
        for (let i = 0; i < n; i++) {
            result += i;
        }
        return result;
    });
    
    // Proxy for property interception
    const person = {
        name: 'John',
        age: 30
    };
    
    const personProxy = new Proxy(person, {
        get(target, property) {
            console.log(`Getting ${property}: ${target[property]}`);
            return target[property];
        },
    
        set(target, property, value) {
            console.log(`Setting ${property} to ${value}`);
    
            if (property === 'age' && value < 0) {
                throw new Error('Age cannot be negative');
            }
    
            target[property] = value;
            return true;
        }
    });
    
    // Generator Functions
    function* fibonacci() {
        let a = 0, b = 1;
    
        while (true) {
            yield a;
            [a, b] = [b, a + b];
        }
    }
    
    const fib = fibonacci();
    console.log(fib.next().value); // 0
    console.log(fib.next().value); // 1
    console.log(fib.next().value); // 1
    console.log(fib.next().value); // 2
    
    // Async Generators
    async function* asyncNumberGenerator() {
        let i = 0;
        while (i < 5) {
            await new Promise(resolve => setTimeout(resolve, 1000));
            yield i++;
        }
    }
    
    // Usage with for-await-of
    async function processNumbers() {
        for await (const num of asyncNumberGenerator()) {
            console.log('Generated:', num);
        }
    }
    JavaScript

    16. JavaScript Frameworks Overview {#frameworks}

    Frontend Framework Ecosystem

    mindmap
      root((Frontend Frameworks))
        React
          Component-based
          Virtual DOM
          JSX
          Large ecosystem
          Meta (Facebook)
        Vue.js
          Progressive
          Template syntax
          Easy learning curve
          Great documentation
        Angular
          Full framework
          TypeScript
          Dependency injection
          Google
        Svelte
          Compile-time
          No virtual DOM
          Small bundle size
          Rich Harris
        Others
          Lit
          Alpine.js
          Solid.js
          Qwik

    Backend Framework Ecosystem

    graph TD
        A[Node.js Backend] --> B[Express.js]
        A --> C[Koa.js]
        A --> D[Fastify]
        A --> E[NestJS]
        A --> F[Next.js API]
    
        B --> G[Minimal & Fast]
        C --> H[Modern & Lightweight]
        D --> I[High Performance]
        E --> J[Enterprise & TypeScript]
        F --> K[Full-Stack React]

    Examples

    // React Component Example
    import React, { useState, useEffect } from 'react';
    
    function UserProfile({ userId }) {
        const [user, setUser] = useState(null);
        const [loading, setLoading] = useState(true);
        const [error, setError] = useState(null);
    
        useEffect(() => {
            async function fetchUser() {
                try {
                    setLoading(true);
                    const response = await fetch(`/api/users/${userId}`);
    
                    if (!response.ok) {
                        throw new Error('Failed to fetch user');
                    }
    
                    const userData = await response.json();
                    setUser(userData);
                } catch (err) {
                    setError(err.message);
                } finally {
                    setLoading(false);
                }
            }
    
            fetchUser();
        }, [userId]);
    
        if (loading) return <div>Loading...</div>;
        if (error) return <div>Error: {error}</div>;
        if (!user) return <div>User not found</div>;
    
        return (
            <div className="user-profile">
                <h2>{user.name}</h2>
                <p>Email: {user.email}</p>
                <p>Age: {user.age}</p>
            </div>
        );
    }
    
    // Vue.js Component Example
    const UserProfile = {
        props: ['userId'],
        data() {
            return {
                user: null,
                loading: true,
                error: null
            };
        },
        async mounted() {
            await this.fetchUser();
        },
        methods: {
            async fetchUser() {
                try {
                    this.loading = true;
                    const response = await fetch(`/api/users/${this.userId}`);
    
                    if (!response.ok) {
                        throw new Error('Failed to fetch user');
                    }
    
                    this.user = await response.json();
                } catch (error) {
                    this.error = error.message;
                } finally {
                    this.loading = false;
                }
            }
        },
        template: `
            <div class="user-profile">
                <div v-if="loading">Loading...</div>
                <div v-else-if="error">Error: {{ error }}</div>
                <div v-else-if="user">
                    <h2>{{ user.name }}</h2>
                    <p>Email: {{ user.email }}</p>
                    <p>Age: {{ user.age }}</p>
                </div>
                <div v-else>User not found</div>
            </div>
        `
    };
    
    // Express.js Server Example
    const express = require('express');
    const app = express();
    
    // Middleware
    app.use(express.json());
    app.use(express.static('public'));
    
    // Routes
    app.get('/api/users', async (req, res) => {
        try {
            const users = await getUsersFromDatabase();
            res.json(users);
        } catch (error) {
            res.status(500).json({ error: error.message });
        }
    });
    
    app.get('/api/users/:id', async (req, res) => {
        try {
            const user = await getUserById(req.params.id);
    
            if (!user) {
                return res.status(404).json({ error: 'User not found' });
            }
    
            res.json(user);
        } catch (error) {
            res.status(500).json({ error: error.message });
        }
    });
    
    app.post('/api/users', async (req, res) => {
        try {
            const newUser = await createUser(req.body);
            res.status(201).json(newUser);
        } catch (error) {
            res.status(400).json({ error: error.message });
        }
    });
    
    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => {
        console.log(`Server running on port ${PORT}`);
    });
    
    // Next.js API Route Example
    // pages/api/users/[id].js
    export default async function handler(req, res) {
        const { id } = req.query;
    
        if (req.method === 'GET') {
            try {
                const user = await getUserById(id);
    
                if (!user) {
                    return res.status(404).json({ error: 'User not found' });
                }
    
                res.status(200).json(user);
            } catch (error) {
                res.status(500).json({ error: error.message });
            }
        } else if (req.method === 'PUT') {
            try {
                const updatedUser = await updateUser(id, req.body);
                res.status(200).json(updatedUser);
            } catch (error) {
                res.status(400).json({ error: error.message });
            }
        } else {
            res.setHeader('Allow', ['GET', 'PUT']);
            res.status(405).end(`Method ${req.method} Not Allowed`);
        }
    }
    JavaScript

    17. Best Practices {#best-practices}

    Code Quality Pyramid

    graph TD
        A[Code Quality] --> B[Readable Code]
        A --> C[Maintainable Code]
        A --> D[Testable Code]
        A --> E[Performant Code]
    
        B --> F[Clear naming]
        B --> G[Consistent formatting]
        B --> H[Good comments]
    
        C --> I[Modular design]
        C --> J[Single responsibility]
        C --> K[Loose coupling]
    
        D --> L[Pure functions]
        D --> M[Dependency injection]
        D --> N[Isolated components]
    
        E --> O[Efficient algorithms]
        E --> P[Memory management]
        E --> Q[Bundle optimization]

    Security Best Practices

    flowchart TD
        A[JavaScript Security] --> B[Input Validation]
        A --> C[Output Sanitization]
        A --> D[Authentication]
        A --> E[Authorization]
        A --> F[HTTPS Only]
    
        B --> G[Validate all inputs]
        B --> H[Use allow-lists]
    
        C --> I[Escape HTML]
        C --> J[Sanitize data]
    
        D --> K[Strong passwords]
        D --> L[Multi-factor auth]
    
        E --> M[Role-based access]
        E --> N[Principle of least privilege]

    Examples

    // Naming Conventions
    // ❌ Bad
    const d = new Date();
    const u = users.filter(x => x.active);
    
    // ✅ Good
    const currentDate = new Date();
    const activeUsers = users.filter(user => user.isActive);
    
    // Function Naming
    // ❌ Bad
    function calc(x, y) {
        return x * y * 0.1;
    }
    
    // ✅ Good
    function calculateDiscountAmount(price, discountPercentage) {
        return price * discountPercentage * 0.01;
    }
    
    // Single Responsibility Principle
    // ❌ Bad - Function does too many things
    function processUser(user) {
        // Validate user
        if (!user.email) throw new Error('Email required');
        if (!user.name) throw new Error('Name required');
    
        // Format user data
        user.email = user.email.toLowerCase();
        user.name = user.name.trim();
    
        // Save to database
        database.save(user);
    
        // Send welcome email
        emailService.sendWelcome(user.email);
    
        return user;
    }
    
    // ✅ Good - Separate concerns
    function validateUser(user) {
        if (!user.email) throw new Error('Email required');
        if (!user.name) throw new Error('Name required');
    }
    
    function formatUser(user) {
        return {
            ...user,
            email: user.email.toLowerCase(),
            name: user.name.trim()
        };
    }
    
    async function createUser(userData) {
        validateUser(userData);
        const formattedUser = formatUser(userData);
    
        const savedUser = await database.save(formattedUser);
        await emailService.sendWelcome(savedUser.email);
    
        return savedUser;
    }
    
    // Pure Functions
    // ❌ Bad - Impure function
    let taxRate = 0.1;
    
    function calculateTax(amount) {
        return amount * taxRate; // Depends on external variable
    }
    
    // ✅ Good - Pure function
    function calculateTax(amount, taxRate) {
        return amount * taxRate;
    }
    
    // Immutability
    // ❌ Bad - Mutates original array
    function addUser(users, newUser) {
        users.push(newUser);
        return users;
    }
    
    // ✅ Good - Returns new array
    function addUser(users, newUser) {
        return [...users, newUser];
    }
    
    // Error Handling Best Practices
    // ❌ Bad - Silent failure
    function parseJSON(jsonString) {
        try {
            return JSON.parse(jsonString);
        } catch (error) {
            return null; // Silent failure
        }
    }
    
    // ✅ Good - Proper error handling
    function parseJSON(jsonString) {
        try {
            return JSON.parse(jsonString);
        } catch (error) {
            throw new Error(`Failed to parse JSON: ${error.message}`);
        }
    }
    
    // Async/Await Best Practices
    // ❌ Bad - Not handling errors
    async function fetchUserData(userId) {
        const response = await fetch(`/api/users/${userId}`);
        const userData = await response.json();
        return userData;
    }
    
    // ✅ Good - Proper error handling
    async function fetchUserData(userId) {
        try {
            const response = await fetch(`/api/users/${userId}`);
    
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
    
            const userData = await response.json();
            return userData;
        } catch (error) {
            console.error('Failed to fetch user data:', error);
            throw error;
        }
    }
    
    // Security Best Practices
    // Input Validation
    function validateEmail(email) {
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return emailRegex.test(email);
    }
    
    function sanitizeInput(input) {
        return input
            .trim()
            .replace(/[<>]/g, '') // Remove potential HTML tags
            .slice(0, 100); // Limit length
    }
    
    // XSS Prevention
    function escapeHtml(unsafe) {
        return unsafe
            .replace(/&/g, "&")
            .replace(/</g, "<")
            .replace(/>/g, ">")
            .replace(/"/g, """)
            .replace(/'/g, "'");
    }
    
    // Environment Variables
    const config = {
        apiUrl: process.env.API_URL || 'http://localhost:3000',
        secretKey: process.env.SECRET_KEY,
        dbUrl: process.env.DATABASE_URL
    };
    
    // Don't expose secrets in client code
    if (typeof window !== 'undefined') {
        delete config.secretKey;
        delete config.dbUrl;
    }
    
    // Performance Best Practices
    // Debouncing for expensive operations
    const debouncedSearch = debounce(async (query) => {
        const results = await searchAPI(query);
        displayResults(results);
    }, 300);
    
    // Lazy loading
    async function loadComponent() {
        const { default: Component } = await import('./HeavyComponent.js');
        return Component;
    }
    
    // Memory management
    class DataManager {
        constructor() {
            this.cache = new Map();
            this.listeners = new Set();
        }
    
        destroy() {
            this.cache.clear();
            this.listeners.clear();
        }
    }
    
    // Code Organization
    // Use consistent file structure
    /*
    src/
      components/
        common/
        features/
      utils/
      services/
      hooks/
      constants/
      types/
    */
    
    // Module exports organization
    // ❌ Bad
    export const UserService = {
        create: () => {},
        update: () => {},
        delete: () => {},
        find: () => {}
    };
    
    // ✅ Good
    export const createUser = () => {};
    export const updateUser = () => {};
    export const deleteUser = () => {};
    export const findUser = () => {};
    
    // Documentation
    /**
     * Calculates the compound interest
     * @param {number} principal - The principal amount
     * @param {number} rate - The annual interest rate (as decimal)
     * @param {number} time - The time period in years
     * @param {number} frequency - Compounding frequency per year
     * @returns {number} The compound interest amount
     * @example
     * const interest = calculateCompoundInterest(1000, 0.05, 2, 12);
     * console.log(interest); // 105.12
     */
    function calculateCompoundInterest(principal, rate, time, frequency = 1) {
        return principal * Math.pow(1 + rate / frequency, frequency * time) - principal;
    }
    JavaScript

    18. Testing {#testing}

    Testing Pyramid

    graph TD
        A[Testing Pyramid] --> B[Unit Tests]
        A --> C[Integration Tests]
        A --> D[E2E Tests]
    
        B --> E[Fast & Isolated]
        B --> F[Test individual functions]
        B --> G[High coverage]
    
        C --> H[Test module interactions]
        C --> I[API testing]
    
        D --> J[Test complete workflows]
        D --> K[User journey testing]
    
        style B fill:#e8f5e8
        style C fill:#fff3cd
        style D fill:#f8d7da

    Testing Tools Ecosystem

    mindmap
      root((JavaScript Testing))
        Test Runners
          Jest
          Mocha
          Vitest
          Karma
        Assertion Libraries
          Jest (built-in)
          Chai
          expect
        Mocking
          Jest mocks
          Sinon
          MSW
        E2E Testing
          Cypress
          Playwright
          Puppeteer
          WebDriver
        Coverage
          Istanbul
          c8
          nyc

    Examples

    // Unit Testing with Jest
    
    // math.js
    export function add(a, b) {
        return a + b;
    }
    
    export function divide(a, b) {
        if (b === 0) {
            throw new Error('Division by zero');
        }
        return a / b;
    }
    
    export function factorial(n) {
        if (n < 0) {
            throw new Error('Factorial of negative number');
        }
        if (n === 0 || n === 1) {
            return 1;
        }
        return n * factorial(n - 1);
    }
    
    // math.test.js
    import { add, divide, factorial } from './math.js';
    
    describe('Math functions', () => {
        describe('add', () => {
            test('should add two positive numbers', () => {
                expect(add(2, 3)).toBe(5);
            });
    
            test('should handle negative numbers', () => {
                expect(add(-1, 1)).toBe(0);
                expect(add(-2, -3)).toBe(-5);
            });
    
            test('should handle decimal numbers', () => {
                expect(add(0.1, 0.2)).toBeCloseTo(0.3);
            });
        });
    
        describe('divide', () => {
            test('should divide two numbers', () => {
                expect(divide(10, 2)).toBe(5);
            });
    
            test('should throw error when dividing by zero', () => {
                expect(() => divide(10, 0)).toThrow('Division by zero');
            });
        });
    
        describe('factorial', () => {
            test('should calculate factorial correctly', () => {
                expect(factorial(0)).toBe(1);
                expect(factorial(1)).toBe(1);
                expect(factorial(5)).toBe(120);
            });
    
            test('should throw error for negative numbers', () => {
                expect(() => factorial(-1)).toThrow('Factorial of negative number');
            });
        });
    });
    
    // Testing Async Functions
    // userService.js
    export class UserService {
        constructor(apiClient) {
            this.apiClient = apiClient;
        }
    
        async getUser(id) {
            const response = await this.apiClient.get(`/users/${id}`);
            return response.data;
        }
    
        async createUser(userData) {
            const response = await this.apiClient.post('/users', userData);
            return response.data;
        }
    }
    
    // userService.test.js
    import { UserService } from './userService.js';
    
    describe('UserService', () => {
        let userService;
        let mockApiClient;
    
        beforeEach(() => {
            mockApiClient = {
                get: jest.fn(),
                post: jest.fn()
            };
            userService = new UserService(mockApiClient);
        });
    
        describe('getUser', () => {
            test('should fetch user by id', async () => {
                const mockUser = { id: 1, name: 'John Doe' };
                mockApiClient.get.mockResolvedValue({ data: mockUser });
    
                const result = await userService.getUser(1);
    
                expect(mockApiClient.get).toHaveBeenCalledWith('/users/1');
                expect(result).toEqual(mockUser);
            });
    
            test('should handle API errors', async () => {
                mockApiClient.get.mockRejectedValue(new Error('Network error'));
    
                await expect(userService.getUser(1)).rejects.toThrow('Network error');
            });
        });
    });
    
    // Integration Testing
    // api.integration.test.js
    import request from 'supertest';
    import app from '../app.js';
    
    describe('User API Integration', () => {
        test('GET /api/users should return users list', async () => {
            const response = await request(app)
                .get('/api/users')
                .expect(200);
    
            expect(Array.isArray(response.body)).toBe(true);
        });
    
        test('POST /api/users should create new user', async () => {
            const newUser = {
                name: 'Test User',
                email: 'test@example.com'
            };
    
            const response = await request(app)
                .post('/api/users')
                .send(newUser)
                .expect(201);
    
            expect(response.body).toMatchObject(newUser);
            expect(response.body.id).toBeDefined();
        });
    });
    
    // E2E Testing with Cypress
    // cypress/e2e/user-registration.cy.js
    describe('User Registration', () => {
        beforeEach(() => {
            cy.visit('/register');
        });
    
        it('should register a new user successfully', () => {
            cy.get('[data-testid="name-input"]').type('John Doe');
            cy.get('[data-testid="email-input"]').type('john@example.com');
            cy.get('[data-testid="password-input"]').type('password123');
            cy.get('[data-testid="submit-button"]').click();
    
            cy.url().should('include', '/dashboard');
            cy.contains('Welcome, John Doe').should('be.visible');
        });
    
        it('should show validation errors for invalid input', () => {
            cy.get('[data-testid="submit-button"]').click();
    
            cy.get('[data-testid="name-error"]').should('contain', 'Name is required');
            cy.get('[data-testid="email-error"]').should('contain', 'Email is required');
        });
    });
    
    // Test Utilities
    // testUtils.js
    export function createMockUser(overrides = {}) {
        return {
            id: 1,
            name: 'Test User',
            email: 'test@example.com',
            age: 25,
            ...overrides
        };
    }
    
    export function waitFor(condition, timeout = 5000) {
        return new Promise((resolve, reject) => {
            const startTime = Date.now();
    
            function check() {
                if (condition()) {
                    resolve();
                } else if (Date.now() - startTime > timeout) {
                    reject(new Error('Timeout waiting for condition'));
                } else {
                    setTimeout(check, 100);
                }
            }
    
            check();
        });
    }
    JavaScript

    19. Performance Optimization {#performance}

    Performance Optimization Areas

    mindmap
      root((Performance Optimization))
        Memory Management
          Avoid memory leaks
          Garbage collection
          Object pooling
          WeakMap/WeakSet
        Bundle Optimization
          Code splitting
          Tree shaking
          Minification
          Compression
        Runtime Performance
          Avoid blocking operations
          Use Web Workers
          Optimize loops
          Debounce/Throttle
        Network Optimization
          Lazy loading
          Caching strategies
          CDN usage
          Image optimization

    JavaScript Execution Optimization

    flowchart TD
        A[JavaScript Performance] --> B[Parsing Phase]
        A --> C[Compilation Phase]
        A --> D[Execution Phase]
    
        B --> E[Minimize parse time]
        B --> F[Code splitting]
    
        C --> G[JIT optimization]
        C --> H[Hot functions]
    
        D --> I[Avoid blocking]
        D --> J[Efficient algorithms]
        D --> K[Memory usage]

    Examples

    // Memory Management Best Practices
    
    // ❌ Bad - Memory leaks
    function createLeakyFunction() {
        const largeArray = new Array(1000000).fill('data');
    
        return function() {
            // This closure keeps largeArray in memory
            console.log('Function called');
        };
    }
    
    // ✅ Good - Proper cleanup
    function createEfficientFunction() {
        return function() {
            console.log('Function called');
        };
    }
    
    // Event listener cleanup
    class Component {
        constructor() {
            this.handleClick = this.handleClick.bind(this);
        }
    
        mount() {
            document.addEventListener('click', this.handleClick);
        }
    
        unmount() {
            document.removeEventListener('click', this.handleClick);
        }
    
        handleClick(event) {
            console.log('Clicked');
        }
    }
    
    // Performance Monitoring
    class PerformanceMonitor {
        static measure(name, fn) {
            return async function(...args) {
                const start = performance.now();
    
                try {
                    const result = await fn.apply(this, args);
                    const end = performance.now();
    
                    console.log(`${name} took ${end - start} milliseconds`);
    
                    // Send to analytics
                    if (typeof gtag !== 'undefined') {
                        gtag('event', 'timing_complete', {
                            name: name,
                            value: Math.round(end - start)
                        });
                    }
    
                    return result;
                } catch (error) {
                    const end = performance.now();
                    console.error(`${name} failed after ${end - start} milliseconds`);
                    throw error;
                }
            };
        }
    
        static markStart(name) {
            performance.mark(`${name}-start`);
        }
    
        static markEnd(name) {
            performance.mark(`${name}-end`);
            performance.measure(name, `${name}-start`, `${name}-end`);
        }
    }
    
    // Efficient DOM Operations
    class DOMOptimizer {
        // Batch DOM updates
        static batchDOMUpdates(updates) {
            const fragment = document.createDocumentFragment();
    
            updates.forEach(update => {
                const element = document.createElement(update.tag);
                element.textContent = update.text;
                if (update.className) {
                    element.className = update.className;
                }
                fragment.appendChild(element);
            });
    
            return fragment;
        }
    
        // Virtual scrolling for large lists
        static createVirtualList(container, items, itemHeight, visibleCount) {
            let scrollTop = 0;
            let startIndex = 0;
            let endIndex = Math.min(visibleCount, items.length);
    
            const totalHeight = items.length * itemHeight;
            const viewport = document.createElement('div');
            viewport.style.height = `${visibleCount * itemHeight}px`;
            viewport.style.overflow = 'auto';
    
            const content = document.createElement('div');
            content.style.height = `${totalHeight}px`;
            content.style.position = 'relative';
    
            function render() {
                content.innerHTML = '';
    
                for (let i = startIndex; i < endIndex; i++) {
                    const item = document.createElement('div');
                    item.style.position = 'absolute';
                    item.style.top = `${i * itemHeight}px`;
                    item.style.height = `${itemHeight}px`;
                    item.textContent = items[i];
                    content.appendChild(item);
                }
            }
    
            viewport.addEventListener('scroll', () => {
                scrollTop = viewport.scrollTop;
                startIndex = Math.floor(scrollTop / itemHeight);
                endIndex = Math.min(startIndex + visibleCount + 1, items.length);
                render();
            });
    
            viewport.appendChild(content);
            container.appendChild(viewport);
            render();
        }
    }
    
    // Efficient Array Operations
    class ArrayOptimizer {
        // Use for...of instead of forEach for performance
        static processLargeArray(array, processor) {
            const results = [];
    
            for (const item of array) {
                results.push(processor(item));
            }
    
            return results;
        }
    
        // Chunked processing to avoid blocking
        static async processInChunks(array, processor, chunkSize = 1000) {
            const results = [];
    
            for (let i = 0; i < array.length; i += chunkSize) {
                const chunk = array.slice(i, i + chunkSize);
    
                const chunkResults = chunk.map(processor);
                results.push(...chunkResults);
    
                // Yield control to browser
                await new Promise(resolve => setTimeout(resolve, 0));
            }
    
            return results;
        }
    
        // Object pooling for frequent allocations
        static createObjectPool(createFn, resetFn, initialSize = 10) {
            const pool = [];
    
            // Pre-populate pool
            for (let i = 0; i < initialSize; i++) {
                pool.push(createFn());
            }
    
            return {
                acquire() {
                    return pool.length > 0 ? pool.pop() : createFn();
                },
    
                release(obj) {
                    resetFn(obj);
                    pool.push(obj);
                }
            };
        }
    }
    
    // Web Workers for CPU-intensive tasks
    // worker.js
    self.onmessage = function(e) {
        const { data, operation } = e.data;
    
        switch (operation) {
            case 'sort':
                const sorted = data.sort((a, b) => a - b);
                self.postMessage({ result: sorted });
                break;
    
            case 'calculate':
                let result = 0;
                for (let i = 0; i < data.iterations; i++) {
                    result += Math.random();
                }
                self.postMessage({ result });
                break;
    
            default:
                self.postMessage({ error: 'Unknown operation' });
        }
    };
    
    // main.js - Using Web Worker
    class WorkerManager {
        constructor() {
            this.worker = new Worker('worker.js');
            this.pendingTasks = new Map();
            this.taskId = 0;
    
            this.worker.onmessage = (e) => {
                const { taskId, result, error } = e.data;
                const task = this.pendingTasks.get(taskId);
    
                if (task) {
                    this.pendingTasks.delete(taskId);
    
                    if (error) {
                        task.reject(new Error(error));
                    } else {
                        task.resolve(result);
                    }
                }
            };
        }
    
        execute(operation, data) {
            return new Promise((resolve, reject) => {
                const taskId = ++this.taskId;
    
                this.pendingTasks.set(taskId, { resolve, reject });
                this.worker.postMessage({ taskId, operation, data });
            });
        }
    
        terminate() {
            this.worker.terminate();
        }
    }
    
    // Lazy Loading Implementation
    class LazyLoader {
        static async loadScript(src) {
            return new Promise((resolve, reject) => {
                const script = document.createElement('script');
                script.src = src;
                script.onload = resolve;
                script.onerror = reject;
                document.head.appendChild(script);
            });
        }
    
        static async loadCSS(href) {
            return new Promise((resolve, reject) => {
                const link = document.createElement('link');
                link.rel = 'stylesheet';
                link.href = href;
                link.onload = resolve;
                link.onerror = reject;
                document.head.appendChild(link);
            });
        }
    
        static observeImages() {
            const imageObserver = new IntersectionObserver((entries) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        const img = entry.target;
                        img.src = img.dataset.src;
                        img.classList.remove('lazy');
                        imageObserver.unobserve(img);
                    }
                });
            });
    
            document.querySelectorAll('img[data-src]').forEach(img => {
                imageObserver.observe(img);
            });
        }
    }
    
    // Caching Strategies
    class CacheManager {
        constructor(maxSize = 100) {
            this.cache = new Map();
            this.maxSize = maxSize;
        }
    
        get(key) {
            if (this.cache.has(key)) {
                // Move to end (LRU)
                const value = this.cache.get(key);
                this.cache.delete(key);
                this.cache.set(key, value);
                return value;
            }
            return null;
        }
    
        set(key, value) {
            if (this.cache.has(key)) {
                this.cache.delete(key);
            } else if (this.cache.size >= this.maxSize) {
                // Remove oldest (first) item
                const firstKey = this.cache.keys().next().value;
                this.cache.delete(firstKey);
            }
    
            this.cache.set(key, value);
        }
    
        clear() {
            this.cache.clear();
        }
    }
    
    // Performance monitoring decorator
    function performanceMonitor(target, propertyName, descriptor) {
        const originalMethod = descriptor.value;
    
        descriptor.value = async function(...args) {
            const start = performance.now();
    
            try {
                const result = await originalMethod.apply(this, args);
                const end = performance.now();
    
                console.log(`${propertyName} executed in ${end - start} milliseconds`);
                return result;
            } catch (error) {
                const end = performance.now();
                console.error(`${propertyName} failed after ${end - start} milliseconds`);
                throw error;
            }
        };
    
        return descriptor;
    }
    
    // Usage examples
    const workerManager = new WorkerManager();
    
    // Offload heavy computation to worker
    workerManager.execute('sort', [3, 1, 4, 1, 5, 9, 2, 6])
        .then(result => console.log('Sorted:', result))
        .catch(error => console.error('Error:', error));
    
    // Cache expensive operations
    const cache = new CacheManager();
    const expensiveOperation = memoize((input) => {
        // Simulate expensive calculation
        return input * Math.random();
    });
    JavaScript

    20. Project Examples {#projects}

    Project Architecture

    graph TD
        A[Project Structure] --> B[Frontend]
        A --> C[Backend]
        A --> D[Database]
        A --> E[DevOps]
    
        B --> F[Components]
        B --> G[Services]
        B --> H[Utils]
        B --> I[Assets]
    
        C --> J[Routes]
        C --> K[Controllers]
        C --> L[Models]
        C --> M[Middleware]
    
        D --> N[Schema Design]
        D --> O[Migrations]
        D --> P[Seed Data]
    
        E --> Q[CI/CD]
        E --> R[Docker]
        E --> S[Testing]
        E --> T[Monitoring]

    Full-Stack Application Flow

    sequenceDiagram
        participant Client
        participant Frontend
        participant Backend
        participant Database
        participant External_API
    
        Client->>Frontend: User Action
        Frontend->>Backend: API Request
        Backend->>Database: Query Data
        Database->>Backend: Return Data
        Backend->>External_API: Fetch Additional Data
        External_API->>Backend: API Response
        Backend->>Frontend: JSON Response
        Frontend->>Client: Update UI

    Project 1: Task Management App

    // Frontend - Task Manager (React)
    import React, { useState, useEffect } from 'react';
    import './TaskManager.css';
    
    const TaskManager = () => {
        const [tasks, setTasks] = useState([]);
        const [newTask, setNewTask] = useState('');
        const [filter, setFilter] = useState('all');
        const [loading, setLoading] = useState(false);
    
        useEffect(() => {
            loadTasks();
        }, []);
    
        const loadTasks = async () => {
            setLoading(true);
            try {
                const response = await fetch('/api/tasks');
                const tasksData = await response.json();
                setTasks(tasksData);
            } catch (error) {
                console.error('Error loading tasks:', error);
            } finally {
                setLoading(false);
            }
        };
    
        const addTask = async (e) => {
            e.preventDefault();
            if (!newTask.trim()) return;
    
            try {
                const response = await fetch('/api/tasks', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        title: newTask,
                        completed: false,
                        createdAt: new Date().toISOString()
                    }),
                });
    
                const task = await response.json();
                setTasks(prev => [...prev, task]);
                setNewTask('');
            } catch (error) {
                console.error('Error adding task:', error);
            }
        };
    
        const toggleTask = async (id, completed) => {
            try {
                const response = await fetch(`/api/tasks/${id}`, {
                    method: 'PATCH',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({ completed }),
                });
    
                const updatedTask = await response.json();
                setTasks(prev => prev.map(task => 
                    task.id === id ? updatedTask : task
                ));
            } catch (error) {
                console.error('Error updating task:', error);
            }
        };
    
        const deleteTask = async (id) => {
            try {
                await fetch(`/api/tasks/${id}`, {
                    method: 'DELETE',
                });
    
                setTasks(prev => prev.filter(task => task.id !== id));
            } catch (error) {
                console.error('Error deleting task:', error);
            }
        };
    
        const filteredTasks = tasks.filter(task => {
            if (filter === 'completed') return task.completed;
            if (filter === 'active') return !task.completed;
            return true;
        });
    
        return (
            <div className="task-manager">
                <h1>Task Manager</h1>
    
                <form onSubmit={addTask} className="add-task-form">
                    <input
                        type="text"
                        value={newTask}
                        onChange={(e) => setNewTask(e.target.value)}
                        placeholder="Add a new task..."
                        className="task-input"
                    />
                    <button type="submit" className="add-button">
                        Add Task
                    </button>
                </form>
    
                <div className="filters">
                    <button 
                        className={filter === 'all' ? 'active' : ''}
                        onClick={() => setFilter('all')}
                    >
                        All
                    </button>
                    <button 
                        className={filter === 'active' ? 'active' : ''}
                        onClick={() => setFilter('active')}
                    >
                        Active
                    </button>
                    <button 
                        className={filter === 'completed' ? 'active' : ''}
                        onClick={() => setFilter('completed')}
                    >
                        Completed
                    </button>
                </div>
    
                {loading ? (
                    <div className="loading">Loading tasks...</div>
                ) : (
                    <ul className="task-list">
                        {filteredTasks.map(task => (
                            <li key={task.id} className={`task-item ${task.completed ? 'completed' : ''}`}>
                                <input
                                    type="checkbox"
                                    checked={task.completed}
                                    onChange={(e) => toggleTask(task.id, e.target.checked)}
                                    className="task-checkbox"
                                />
                                <span className="task-title">{task.title}</span>
                                <button 
                                    onClick={() => deleteTask(task.id)}
                                    className="delete-button"
                                >
                                    Delete
                                </button>
                            </li>
                        ))}
                    </ul>
                )}
    
                <div className="task-summary">
                    Total: {tasks.length} | 
                    Active: {tasks.filter(t => !t.completed).length} | 
                    Completed: {tasks.filter(t => t.completed).length}
                </div>
            </div>
        );
    };
    
    export default TaskManager;
    
    // Backend - Express.js API
    import express from 'express';
    import cors from 'cors';
    import { v4 as uuidv4 } from 'uuid';
    
    const app = express();
    const PORT = process.env.PORT || 3001;
    
    // Middleware
    app.use(cors());
    app.use(express.json());
    
    // In-memory storage (use database in production)
    let tasks = [
        {
            id: uuidv4(),
            title: 'Learn JavaScript',
            completed: false,
            createdAt: new Date().toISOString()
        },
        {
            id: uuidv4(),
            title: 'Build a project',
            completed: true,
            createdAt: new Date().toISOString()
        }
    ];
    
    // Routes
    app.get('/api/tasks', (req, res) => {
        res.json(tasks);
    });
    
    app.post('/api/tasks', (req, res) => {
        const { title, completed = false } = req.body;
    
        if (!title || title.trim().length === 0) {
            return res.status(400).json({ error: 'Title is required' });
        }
    
        const newTask = {
            id: uuidv4(),
            title: title.trim(),
            completed,
            createdAt: new Date().toISOString()
        };
    
        tasks.push(newTask);
        res.status(201).json(newTask);
    });
    
    app.patch('/api/tasks/:id', (req, res) => {
        const { id } = req.params;
        const { title, completed } = req.body;
    
        const taskIndex = tasks.findIndex(task => task.id === id);
    
        if (taskIndex === -1) {
            return res.status(404).json({ error: 'Task not found' });
        }
    
        if (title !== undefined) {
            tasks[taskIndex].title = title.trim();
        }
    
        if (completed !== undefined) {
            tasks[taskIndex].completed = completed;
        }
    
        tasks[taskIndex].updatedAt = new Date().toISOString();
    
        res.json(tasks[taskIndex]);
    });
    
    app.delete('/api/tasks/:id', (req, res) => {
        const { id } = req.params;
        const taskIndex = tasks.findIndex(task => task.id === id);
    
        if (taskIndex === -1) {
            return res.status(404).json({ error: 'Task not found' });
        }
    
        tasks.splice(taskIndex, 1);
        res.status(204).send();
    });
    
    // Error handling middleware
    app.use((error, req, res, next) => {
        console.error('Error:', error);
        res.status(500).json({ error: 'Internal server error' });
    });
    
    app.listen(PORT, () => {
        console.log(`Server running on port ${PORT}`);
    });
    
    // Project 2: Real-time Chat Application
    // WebSocket Server (Node.js)
    import WebSocket, { WebSocketServer } from 'ws';
    import { v4 as uuidv4 } from 'uuid';
    
    class ChatServer {
        constructor(port = 8080) {
            this.wss = new WebSocketServer({ port });
            this.clients = new Map();
            this.rooms = new Map();
    
            this.wss.on('connection', this.handleConnection.bind(this));
            console.log(`Chat server running on port ${port}`);
        }
    
        handleConnection(ws) {
            const clientId = uuidv4();
            console.log(`Client ${clientId} connected`);
    
            this.clients.set(clientId, {
                ws,
                id: clientId,
                username: null,
                room: null
            });
    
            ws.on('message', (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    this.handleMessage(clientId, message);
                } catch (error) {
                    console.error('Invalid message format:', error);
                }
            });
    
            ws.on('close', () => {
                this.handleDisconnection(clientId);
            });
    
            ws.on('error', (error) => {
                console.error(`Client ${clientId} error:`, error);
            });
        }
    
        handleMessage(clientId, message) {
            const client = this.clients.get(clientId);
            if (!client) return;
    
            switch (message.type) {
                case 'join':
                    this.handleJoin(clientId, message.username, message.room);
                    break;
    
                case 'chat':
                    this.handleChat(clientId, message.text);
                    break;
    
                case 'leave':
                    this.handleLeave(clientId);
                    break;
    
                default:
                    console.log('Unknown message type:', message.type);
            }
        }
    
        handleJoin(clientId, username, roomName) {
            const client = this.clients.get(clientId);
            if (!client) return;
    
            client.username = username;
            client.room = roomName;
    
            if (!this.rooms.has(roomName)) {
                this.rooms.set(roomName, new Set());
            }
    
            this.rooms.get(roomName).add(clientId);
    
            // Notify room about new user
            this.broadcastToRoom(roomName, {
                type: 'user_joined',
                username,
                timestamp: new Date().toISOString()
            }, clientId);
    
            // Send room info to new user
            this.sendToClient(clientId, {
                type: 'joined',
                room: roomName,
                users: Array.from(this.rooms.get(roomName))
                    .map(id => this.clients.get(id)?.username)
                    .filter(Boolean)
            });
        }
    
        handleChat(clientId, text) {
            const client = this.clients.get(clientId);
            if (!client || !client.room) return;
    
            const message = {
                type: 'chat',
                username: client.username,
                text,
                timestamp: new Date().toISOString()
            };
    
            this.broadcastToRoom(client.room, message);
        }
    
        handleLeave(clientId) {
            const client = this.clients.get(clientId);
            if (!client || !client.room) return;
    
            const room = this.rooms.get(client.room);
            if (room) {
                room.delete(clientId);
    
                this.broadcastToRoom(client.room, {
                    type: 'user_left',
                    username: client.username,
                    timestamp: new Date().toISOString()
                }, clientId);
    
                if (room.size === 0) {
                    this.rooms.delete(client.room);
                }
            }
    
            client.room = null;
        }
    
        handleDisconnection(clientId) {
            console.log(`Client ${clientId} disconnected`);
            this.handleLeave(clientId);
            this.clients.delete(clientId);
        }
    
        sendToClient(clientId, message) {
            const client = this.clients.get(clientId);
            if (client && client.ws.readyState === WebSocket.OPEN) {
                client.ws.send(JSON.stringify(message));
            }
        }
    
        broadcastToRoom(roomName, message, excludeClientId = null) {
            const room = this.rooms.get(roomName);
            if (!room) return;
    
            room.forEach(clientId => {
                if (clientId !== excludeClientId) {
                    this.sendToClient(clientId, message);
                }
            });
        }
    }
    
    // Start chat server
    new ChatServer(8080);
    
    // Chat Client (Frontend)
    class ChatClient {
        constructor(serverUrl = 'ws://localhost:8080') {
            this.serverUrl = serverUrl;
            this.ws = null;
            this.connected = false;
            this.username = null;
            this.room = null;
    
            this.messageHandlers = {
                joined: this.handleJoined.bind(this),
                chat: this.handleChat.bind(this),
                user_joined: this.handleUserJoined.bind(this),
                user_left: this.handleUserLeft.bind(this)
            };
        }
    
        connect() {
            return new Promise((resolve, reject) => {
                this.ws = new WebSocket(this.serverUrl);
    
                this.ws.onopen = () => {
                    this.connected = true;
                    console.log('Connected to chat server');
                    resolve();
                };
    
                this.ws.onmessage = (event) => {
                    try {
                        const message = JSON.parse(event.data);
                        this.handleMessage(message);
                    } catch (error) {
                        console.error('Error parsing message:', error);
                    }
                };
    
                this.ws.onclose = () => {
                    this.connected = false;
                    console.log('Disconnected from chat server');
                };
    
                this.ws.onerror = (error) => {
                    console.error('WebSocket error:', error);
                    reject(error);
                };
            });
        }
    
        joinRoom(username, room) {
            if (!this.connected) {
                throw new Error('Not connected to server');
            }
    
            this.username = username;
            this.room = room;
    
            this.sendMessage({
                type: 'join',
                username,
                room
            });
        }
    
        sendChat(text) {
            if (!this.connected || !this.room) {
                throw new Error('Not in a room');
            }
    
            this.sendMessage({
                type: 'chat',
                text
            });
        }
    
        leaveRoom() {
            if (!this.connected || !this.room) return;
    
            this.sendMessage({
                type: 'leave'
            });
    
            this.room = null;
        }
    
        sendMessage(message) {
            if (this.ws && this.ws.readyState === WebSocket.OPEN) {
                this.ws.send(JSON.stringify(message));
            }
        }
    
        handleMessage(message) {
            const handler = this.messageHandlers[message.type];
            if (handler) {
                handler(message);
            } else {
                console.log('Unhandled message type:', message.type);
            }
        }
    
        handleJoined(message) {
            console.log(`Joined room: ${message.room}`);
            this.displayMessage(`Joined room: ${message.room}`, 'system');
            this.updateUserList(message.users);
        }
    
        handleChat(message) {
            this.displayMessage(`${message.username}: ${message.text}`, 'chat');
        }
    
        handleUserJoined(message) {
            this.displayMessage(`${message.username} joined the room`, 'system');
        }
    
        handleUserLeft(message) {
            this.displayMessage(`${message.username} left the room`, 'system');
        }
    
        displayMessage(text, type = 'chat') {
            const messagesContainer = document.getElementById('messages');
            const messageElement = document.createElement('div');
            messageElement.className = `message ${type}`;
            messageElement.textContent = text;
            messagesContainer.appendChild(messageElement);
            messagesContainer.scrollTop = messagesContainer.scrollHeight;
        }
    
        updateUserList(users) {
            const userList = document.getElementById('user-list');
            userList.innerHTML = '';
    
            users.forEach(username => {
                const userElement = document.createElement('div');
                userElement.className = 'user';
                userElement.textContent = username;
                userList.appendChild(userElement);
            });
        }
    
        disconnect() {
            if (this.ws) {
                this.ws.close();
            }
        }
    }
    
    // Usage example
    const chatClient = new ChatClient();
    
    document.getElementById('connect-btn').addEventListener('click', async () => {
        try {
            await chatClient.connect();
    
            const username = document.getElementById('username').value;
            const room = document.getElementById('room').value;
    
            chatClient.joinRoom(username, room);
        } catch (error) {
            console.error('Failed to connect:', error);
        }
    });
    
    document.getElementById('send-btn').addEventListener('click', () => {
        const messageInput = document.getElementById('message-input');
        const text = messageInput.value.trim();
    
        if (text) {
            chatClient.sendChat(text);
            messageInput.value = '';
        }
    });
    JavaScript

    Conclusion

    This comprehensive JavaScript guide covers everything from basic concepts to advanced topics and real-world applications. The key to mastering JavaScript is:

    1. Practice Regularly: Build projects and experiment with code
    2. Understand Core Concepts: Focus on fundamentals like closures, prototypes, and async programming
    3. Stay Updated: JavaScript evolves rapidly with new features and best practices
    4. Use Modern Tools: Leverage frameworks, build tools, and testing libraries
    5. Write Clean Code: Follow best practices for maintainable and readable code
    6. Performance Matters: Optimize for speed and efficiency
    7. Test Your Code: Write tests to ensure reliability
    8. Learn from Others: Read open-source code and participate in the community

    Next Steps

    1. Choose a Specialization: Frontend frameworks (React, Vue, Angular) or backend (Node.js)
    2. Build Projects: Start with small projects and gradually increase complexity
    3. Contribute to Open Source: Learn from experienced developers
    4. Join Communities: Participate in JavaScript communities and forums
    5. Continuous Learning: Keep up with new features and best practices

    JavaScript is a powerful and versatile language that enables you to build amazing applications across different platforms. With consistent practice and the knowledge from this guide, you’ll be well on your way to becoming a JavaScript expert!

    JavaScript Cheatsheet

    Table of Contents


    Variables

    // var - function-scoped, can be redeclared
    var name = "John";
    
    // let - block-scoped, can be reassigned
    let age = 25;
    
    // const - block-scoped, cannot be reassigned
    const PI = 3.14159;
    
    // Multiple declarations
    let x = 5, y = 10, z = 15;
    JavaScript

    Data Types

    // Primitive Types
    let str = "Hello";              // String
    let num = 42;                   // Number
    let bool = true;                // Boolean
    let nothing = null;             // Null
    let undef = undefined;          // Undefined
    let sym = Symbol('unique');     // Symbol (ES6)
    let bigInt = 1234567890123456789012345678901234567890n; // BigInt
    
    // Reference Types
    let arr = [1, 2, 3];           // Array
    let obj = {name: "John"};      // Object
    let func = function() {};      // Function
    
    // Type checking
    typeof "Hello"                  // "string"
    typeof 42                       // "number"
    typeof true                     // "boolean"
    typeof undefined                // "undefined"
    typeof Symbol()                 // "symbol"
    typeof {}                       // "object"
    typeof []                       // "object"
    typeof null                     // "object" (known bug)
    Array.isArray([])              // true
    JavaScript

    Operators

    // Arithmetic
    let sum = 5 + 3;               // 8
    let diff = 5 - 3;              // 2
    let prod = 5 * 3;              // 15
    let quot = 5 / 2;              // 2.5
    let rem = 5 % 2;               // 1 (remainder)
    let exp = 2 ** 3;              // 8 (exponentiation)
    
    // Increment/Decrement
    let x = 5;
    x++;                           // 6 (post-increment)
    ++x;                           // 7 (pre-increment)
    x--;                           // 6 (post-decrement)
    --x;                           // 5 (pre-decrement)
    
    // Assignment
    let a = 10;
    a += 5;                        // a = a + 5
    a -= 3;                        // a = a - 3
    a *= 2;                        // a = a * 2
    a /= 4;                        // a = a / 4
    a %= 3;                        // a = a % 3
    
    // Comparison
    5 == "5"                       // true (loose equality)
    5 === "5"                      // false (strict equality)
    5 != "5"                       // false
    5 !== "5"                      // true
    5 > 3                          // true
    5 < 3                          // false
    5 >= 5                         // true
    5 <= 5                         // true
    
    // Logical
    true && false                  // false (AND)
    true || false                  // true (OR)
    !true                          // false (NOT)
    
    // Ternary
    let result = (age >= 18) ? "Adult" : "Minor";
    
    // Nullish Coalescing
    let value = null ?? "default"; // "default"
    let value2 = 0 ?? "default";   // 0
    
    // Optional Chaining
    let name = user?.profile?.name; // undefined if user or profile is null/undefined
    JavaScript

    Strings

    // String creation
    let str1 = "Hello";
    let str2 = 'World';
    let str3 = `Template ${str1}`;  // Template literal
    
    // String properties
    str1.length                     // 5
    
    // Common methods
    str1.charAt(0)                  // "H"
    str1.charCodeAt(0)              // 72
    str1.concat(" ", str2)          // "Hello World"
    str1.includes("ell")            // true
    str1.indexOf("l")               // 2
    str1.lastIndexOf("l")           // 3
    str1.slice(0, 3)                // "Hel"
    str1.substring(0, 3)            // "Hel"
    str1.substr(1, 3)               // "ell" (deprecated)
    str1.toLowerCase()              // "hello"
    str1.toUpperCase()              // "HELLO"
    str1.trim()                     // removes whitespace
    str1.trimStart()                // removes leading whitespace
    str1.trimEnd()                  // removes trailing whitespace
    str1.split("")                  // ["H", "e", "l", "l", "o"]
    str1.repeat(2)                  // "HelloHello"
    str1.replace("l", "L")          // "HeLlo"
    str1.replaceAll("l", "L")       // "HeLLo"
    str1.startsWith("He")           // true
    str1.endsWith("lo")             // true
    str1.padStart(10, "*")          // "*****Hello"
    str1.padEnd(10, "*")            // "Hello*****"
    
    // Template literals
    let name = "John";
    let age = 30;
    let message = `My name is ${name} and I'm ${age} years old`;
    let multiline = `Line 1
    Line 2
    Line 3`;
    JavaScript

    Arrays

    // Array creation
    let arr = [1, 2, 3, 4, 5];
    let arr2 = new Array(1, 2, 3);
    let arr3 = Array.of(1, 2, 3);
    let arr4 = Array.from("Hello"); // ["H", "e", "l", "l", "o"]
    
    // Array properties
    arr.length                      // 5
    
    // Adding/Removing elements
    arr.push(6)                     // Add to end: [1,2,3,4,5,6]
    arr.pop()                       // Remove from end: returns 6
    arr.unshift(0)                  // Add to start: [0,1,2,3,4,5]
    arr.shift()                     // Remove from start: returns 0
    arr.splice(2, 1, 99)            // Remove/add at index: [1,2,99,4,5]
    
    // Finding elements
    arr.indexOf(3)                  // 2
    arr.lastIndexOf(3)              // 2
    arr.includes(3)                 // true
    arr.find(x => x > 3)            // 4
    arr.findIndex(x => x > 3)       // 3
    arr.findLast(x => x > 3)        // 5
    arr.findLastIndex(x => x > 3)   // 4
    
    // Slicing and joining
    arr.slice(1, 3)                 // [2, 3] (doesn't modify original)
    arr.concat([6, 7])              // [1,2,3,4,5,6,7]
    arr.join(", ")                  // "1, 2, 3, 4, 5"
    
    // Sorting and reversing
    arr.sort()                      // Sort alphabetically
    arr.sort((a, b) => a - b)       // Sort numerically ascending
    arr.sort((a, b) => b - a)       // Sort numerically descending
    arr.reverse()                   // Reverse array
    
    // Filtering and mapping
    arr.filter(x => x > 2)          // [3, 4, 5]
    arr.map(x => x * 2)             // [2, 4, 6, 8, 10]
    arr.forEach((item, index) => console.log(item));
    
    // Reducing
    arr.reduce((acc, curr) => acc + curr, 0)      // 15 (sum)
    arr.reduceRight((acc, curr) => acc + curr, 0) // 15
    
    // Testing
    arr.every(x => x > 0)           // true (all elements)
    arr.some(x => x > 4)            // true (at least one)
    
    // Flattening
    [[1, 2], [3, 4]].flat()         // [1, 2, 3, 4]
    [[1, [2, [3]]]].flat(2)         // [1, 2, 3]
    arr.flatMap(x => [x, x * 2])    // [1, 2, 2, 4, 3, 6, ...]
    
    // Other useful methods
    arr.fill(0)                     // Fill with 0
    arr.copyWithin(0, 3, 5)         // Copy elements within array
    Array.isArray(arr)              // true
    [...new Set([1, 2, 2, 3])]      // [1, 2, 3] (remove duplicates)
    JavaScript

    Objects

    // Object creation
    let person = {
      name: "John",
      age: 30,
      city: "New York"
    };
    
    // Object literals
    let obj = {};
    let obj2 = new Object();
    
    // Accessing properties
    person.name                     // "John"
    person["age"]                   // 30
    
    // Adding/Modifying properties
    person.email = "john@example.com";
    person["phone"] = "123-456-7890";
    
    // Deleting properties
    delete person.city;
    
    // Checking properties
    "name" in person                // true
    person.hasOwnProperty("name")   // true
    
    // Object methods
    Object.keys(person)             // ["name", "age", "email", "phone"]
    Object.values(person)           // ["John", 30, "john@example.com", "123-456-7890"]
    Object.entries(person)          // [["name", "John"], ["age", 30], ...]
    
    // Object manipulation
    Object.assign({}, person)       // Copy object
    {...person}                     // Spread syntax (shallow copy)
    Object.freeze(person)           // Make immutable
    Object.seal(person)             // Prevent adding/removing properties
    Object.isFrozen(person)         // Check if frozen
    Object.isSealed(person)         // Check if sealed
    
    // Object.defineProperty
    Object.defineProperty(person, 'id', {
      value: 123,
      writable: false,
      enumerable: true,
      configurable: false
    });
    
    // Computed property names
    let key = "dynamicKey";
    let obj3 = {
      [key]: "value",
      [`${key}2`]: "value2"
    };
    
    // Shorthand properties
    let name = "John";
    let age = 30;
    let user = { name, age };       // {name: "John", age: 30}
    
    // Method shorthand
    let calculator = {
      add(a, b) { return a + b; },
      subtract(a, b) { return a - b; }
    };
    JavaScript

    Functions

    // Function declaration
    function greet(name) {
      return `Hello, ${name}!`;
    }
    
    // Function expression
    const greet2 = function(name) {
      return `Hello, ${name}!`;
    };
    
    // Arrow function
    const greet3 = (name) => `Hello, ${name}!`;
    const add = (a, b) => a + b;
    const square = x => x * x;      // Single parameter, no parentheses
    
    // Default parameters
    function greet4(name = "Guest") {
      return `Hello, ${name}!`;
    }
    
    // Rest parameters
    function sum(...numbers) {
      return numbers.reduce((acc, curr) => acc + curr, 0);
    }
    
    // IIFE (Immediately Invoked Function Expression)
    (function() {
      console.log("Executed immediately");
    })();
    
    // Higher-order functions
    function createMultiplier(multiplier) {
      return function(number) {
        return number * multiplier;
      };
    }
    const double = createMultiplier(2);
    double(5);                      // 10
    
    // Callback functions
    function processArray(arr, callback) {
      return arr.map(callback);
    }
    processArray([1, 2, 3], x => x * 2); // [2, 4, 6]
    
    // Generator functions
    function* generateSequence() {
      yield 1;
      yield 2;
      yield 3;
    }
    const generator = generateSequence();
    generator.next().value;         // 1
    generator.next().value;         // 2
    
    // Function methods
    function greet5(greeting, punctuation) {
      return `${greeting}, ${this.name}${punctuation}`;
    }
    const person1 = { name: "John" };
    greet5.call(person1, "Hello", "!");      // "Hello, John!"
    greet5.apply(person1, ["Hi", "."]);      // "Hi, John."
    const boundGreet = greet5.bind(person1); // Creates new function
    boundGreet("Hey", "!");                   // "Hey, John!"
    JavaScript

    Control Flow

    // if...else
    if (age >= 18) {
      console.log("Adult");
    } else if (age >= 13) {
      console.log("Teenager");
    } else {
      console.log("Child");
    }
    
    // switch
    switch (day) {
      case "Monday":
        console.log("Start of week");
        break;
      case "Friday":
        console.log("TGIF!");
        break;
      case "Saturday":
      case "Sunday":
        console.log("Weekend!");
        break;
      default:
        console.log("Midweek");
    }
    
    // Conditional (ternary) operator
    let status = (age >= 18) ? "Adult" : "Minor";
    
    // Nullish coalescing
    let name = username ?? "Guest";
    
    // Optional chaining
    let userCity = user?.address?.city;
    JavaScript

    Loops

    // for loop
    for (let i = 0; i < 5; i++) {
      console.log(i);
    }
    
    // for...of (arrays, strings, iterables)
    const arr = [1, 2, 3, 4, 5];
    for (const num of arr) {
      console.log(num);
    }
    
    // for...in (object properties)
    const obj = {a: 1, b: 2, c: 3};
    for (const key in obj) {
      console.log(key, obj[key]);
    }
    
    // while loop
    let i = 0;
    while (i < 5) {
      console.log(i);
      i++;
    }
    
    // do...while loop
    let j = 0;
    do {
      console.log(j);
      j++;
    } while (j < 5);
    
    // forEach
    arr.forEach((item, index, array) => {
      console.log(item, index);
    });
    
    // break and continue
    for (let i = 0; i < 10; i++) {
      if (i === 5) continue;        // Skip 5
      if (i === 8) break;           // Exit loop
      console.log(i);
    }
    
    // Labeled statements
    outer: for (let i = 0; i < 3; i++) {
      for (let j = 0; j < 3; j++) {
        if (i === 1 && j === 1) break outer;
        console.log(i, j);
      }
    }
    JavaScript

    ES6+ Features

    // Template literals
    const name = "John";
    const message = `Hello, ${name}!`;
    
    // Arrow functions
    const add = (a, b) => a + b;
    
    // Destructuring
    const [a, b] = [1, 2];
    const {name: userName, age} = {name: "John", age: 30};
    
    // Spread operator
    const arr1 = [1, 2, 3];
    const arr2 = [...arr1, 4, 5];
    const obj1 = {a: 1, b: 2};
    const obj2 = {...obj1, c: 3};
    
    // Rest parameters
    function sum(...numbers) {
      return numbers.reduce((a, b) => a + b);
    }
    
    // Default parameters
    function greet(name = "Guest") {
      return `Hello, ${name}`;
    }
    
    // Enhanced object literals
    const x = 10, y = 20;
    const point = { x, y };         // {x: 10, y: 20}
    
    // Computed property names
    const key = "dynamicKey";
    const obj = { [key]: "value" };
    
    // let and const
    let mutableVar = 10;
    const immutableVar = 20;
    
    // Classes
    class Person {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
    
      greet() {
        return `Hello, I'm ${this.name}`;
      }
    }
    
    // Modules
    // export const PI = 3.14;
    // import { PI } from './math.js';
    
    // Promises
    const promise = new Promise((resolve, reject) => {
      setTimeout(() => resolve("Done!"), 1000);
    });
    
    // async/await
    async function fetchData() {
      const response = await fetch(url);
      const data = await response.json();
      return data;
    }
    
    // Symbol
    const sym = Symbol('description');
    
    // Map and Set
    const map = new Map();
    map.set('key', 'value');
    const set = new Set([1, 2, 3]);
    
    // WeakMap and WeakSet
    const weakMap = new WeakMap();
    const weakSet = new WeakSet();
    
    // Proxy
    const proxy = new Proxy(target, handler);
    
    // Reflect
    Reflect.get(obj, 'property');
    
    // BigInt
    const bigNum = 1234567890123456789012345678901234567890n;
    
    // Nullish coalescing
    const value = null ?? 'default';
    
    // Optional chaining
    const name = user?.profile?.name;
    
    // Logical assignment operators
    x ??= 10;                       // x = x ?? 10
    x &&= 10;                       // x = x && 10
    x ||= 10;                       // x = x || 10
    
    // Numeric separators
    const billion = 1_000_000_000;
    
    // Promise.allSettled
    await Promise.allSettled([promise1, promise2]);
    
    // String.matchAll
    const matches = str.matchAll(regex);
    
    // globalThis
    globalThis.console.log("Works everywhere");
    JavaScript

    Destructuring

    // Array destructuring
    const [a, b, c] = [1, 2, 3];
    const [first, , third] = [1, 2, 3];  // Skip elements
    const [x, ...rest] = [1, 2, 3, 4];   // rest = [2, 3, 4]
    const [p = 10, q = 20] = [5];        // Default values: p=5, q=20
    
    // Object destructuring
    const {name, age} = {name: "John", age: 30};
    const {name: userName} = {name: "John"};  // Rename
    const {city = "NYC"} = {};           // Default value
    const {a, ...others} = {a: 1, b: 2, c: 3}; // others = {b: 2, c: 3}
    
    // Nested destructuring
    const {name, address: {city, zip}} = {
      name: "John",
      address: {city: "NYC", zip: "10001"}
    };
    
    // Function parameters
    function greet({name, age}) {
      return `${name} is ${age} years old`;
    }
    greet({name: "John", age: 30});
    
    // Swapping variables
    let x = 1, y = 2;
    [x, y] = [y, x];                // x=2, y=1
    JavaScript

    Spread & Rest

    // Spread operator with arrays
    const arr1 = [1, 2, 3];
    const arr2 = [4, 5, 6];
    const combined = [...arr1, ...arr2];  // [1,2,3,4,5,6]
    const copy = [...arr1];               // Shallow copy
    
    // Spread operator with objects
    const obj1 = {a: 1, b: 2};
    const obj2 = {c: 3, d: 4};
    const merged = {...obj1, ...obj2};    // {a:1, b:2, c:3, d:4}
    const overridden = {...obj1, b: 99};  // {a:1, b:99}
    
    // Spread with function calls
    const numbers = [1, 2, 3];
    Math.max(...numbers);                 // 3
    
    // Rest parameters in functions
    function sum(...numbers) {
      return numbers.reduce((a, b) => a + b, 0);
    }
    sum(1, 2, 3, 4, 5);                   // 15
    
    // Rest in destructuring
    const [first, ...rest] = [1, 2, 3, 4];  // first=1, rest=[2,3,4]
    const {a, ...others} = {a: 1, b: 2, c: 3}; // a=1, others={b:2,c:3}
    JavaScript

    Promises & Async/Await

    // Creating a Promise
    const promise = new Promise((resolve, reject) => {
      setTimeout(() => {
        const success = true;
        if (success) {
          resolve("Operation successful");
        } else {
          reject("Operation failed");
        }
      }, 1000);
    });
    
    // Using Promises
    promise
      .then(result => console.log(result))
      .catch(error => console.error(error))
      .finally(() => console.log("Cleanup"));
    
    // Chaining Promises
    fetch(url)
      .then(response => response.json())
      .then(data => console.log(data))
      .catch(error => console.error(error));
    
    // Promise.all (waits for all)
    Promise.all([promise1, promise2, promise3])
      .then(results => console.log(results))
      .catch(error => console.error(error));
    
    // Promise.race (first to complete)
    Promise.race([promise1, promise2, promise3])
      .then(result => console.log(result));
    
    // Promise.allSettled (waits for all, doesn't fail)
    Promise.allSettled([promise1, promise2, promise3])
      .then(results => console.log(results));
    
    // Promise.any (first successful)
    Promise.any([promise1, promise2, promise3])
      .then(result => console.log(result));
    
    // Async/Await
    async function fetchData() {
      try {
        const response = await fetch(url);
        const data = await response.json();
        return data;
      } catch (error) {
        console.error(error);
      }
    }
    
    // Async with Promise.all
    async function fetchMultiple() {
      const [data1, data2] = await Promise.all([
        fetch(url1).then(r => r.json()),
        fetch(url2).then(r => r.json())
      ]);
      return { data1, data2 };
    }
    
    // Async IIFE
    (async () => {
      const data = await fetchData();
      console.log(data);
    })();
    
    // Error handling with async/await
    async function safeFunction() {
      try {
        const result = await riskyOperation();
        return result;
      } catch (error) {
        console.error("Error:", error);
        throw error;
      } finally {
        console.log("Cleanup");
      }
    }
    JavaScript

    DOM Manipulation

    // Selecting elements
    document.getElementById('myId');
    document.getElementsByClassName('myClass');
    document.getElementsByTagName('div');
    document.querySelector('.myClass');
    document.querySelectorAll('div.myClass');
    
    // Creating elements
    const div = document.createElement('div');
    const text = document.createTextNode('Hello');
    
    // Modifying elements
    element.textContent = "New text";
    element.innerHTML = "<strong>Bold</strong>";
    element.setAttribute('class', 'myClass');
    element.getAttribute('class');
    element.removeAttribute('class');
    element.classList.add('newClass');
    element.classList.remove('oldClass');
    element.classList.toggle('active');
    element.classList.contains('active');
    
    // Styling
    element.style.color = "red";
    element.style.backgroundColor = "blue";
    element.style.fontSize = "16px";
    
    // Adding/Removing elements
    parent.appendChild(child);
    parent.insertBefore(newChild, existingChild);
    parent.removeChild(child);
    element.remove();
    parent.replaceChild(newChild, oldChild);
    
    // Traversing DOM
    element.parentNode;
    element.parentElement;
    element.children;
    element.firstChild;
    element.firstElementChild;
    element.lastChild;
    element.lastElementChild;
    element.nextSibling;
    element.nextElementSibling;
    element.previousSibling;
    element.previousElementSibling;
    
    // Element properties
    element.id;
    element.className;
    element.tagName;
    element.value;                  // For inputs
    element.checked;                // For checkboxes
    element.innerHTML;
    element.textContent;
    element.innerText;
    
    // Cloning
    element.cloneNode(true);        // Deep clone
    element.cloneNode(false);       // Shallow clone
    JavaScript

    Event Handling

    // Adding event listeners
    element.addEventListener('click', function(e) {
      console.log('Clicked!');
    });
    
    // Arrow function event listener
    element.addEventListener('click', (e) => {
      console.log(e.target);
    });
    
    // Event listener with options
    element.addEventListener('click', handler, {
      once: true,                   // Remove after first trigger
      capture: true,                // Capture phase
      passive: true                 // Won't call preventDefault
    });
    
    // Removing event listeners
    function handleClick(e) {
      console.log('Clicked!');
    }
    element.addEventListener('click', handleClick);
    element.removeEventListener('click', handleClick);
    
    // Common events
    element.addEventListener('click', handler);
    element.addEventListener('dblclick', handler);
    element.addEventListener('mousedown', handler);
    element.addEventListener('mouseup', handler);
    element.addEventListener('mouseover', handler);
    element.addEventListener('mouseout', handler);
    element.addEventListener('mousemove', handler);
    element.addEventListener('keydown', handler);
    element.addEventListener('keyup', handler);
    element.addEventListener('keypress', handler);
    element.addEventListener('focus', handler);
    element.addEventListener('blur', handler);
    element.addEventListener('submit', handler);
    element.addEventListener('change', handler);
    element.addEventListener('input', handler);
    element.addEventListener('load', handler);
    element.addEventListener('DOMContentLoaded', handler);
    
    // Event object properties
    e.target;                       // Element that triggered event
    e.currentTarget;                // Element with event listener
    e.type;                         // Event type
    e.preventDefault();             // Prevent default behavior
    e.stopPropagation();            // Stop event bubbling
    e.stopImmediatePropagation();   // Stop other listeners
    
    // Mouse events
    e.clientX, e.clientY;           // Mouse position (viewport)
    e.pageX, e.pageY;               // Mouse position (document)
    e.button;                       // Mouse button pressed
    
    // Keyboard events
    e.key;                          // Key pressed
    e.code;                         // Physical key code
    e.keyCode;                      // Deprecated
    e.altKey, e.ctrlKey, e.shiftKey, e.metaKey;
    
    // Event delegation
    document.addEventListener('click', (e) => {
      if (e.target.matches('.btn')) {
        console.log('Button clicked');
      }
    });
    
    // Custom events
    const customEvent = new CustomEvent('myEvent', {
      detail: { message: 'Custom event data' }
    });
    element.dispatchEvent(customEvent);
    element.addEventListener('myEvent', (e) => {
      console.log(e.detail.message);
    });
    JavaScript

    Error Handling

    // try...catch
    try {
      // Code that might throw an error
      const result = riskyOperation();
    } catch (error) {
      console.error("Error:", error.message);
    } finally {
      // Always executes
      console.log("Cleanup");
    }
    
    // Throwing errors
    throw new Error("Something went wrong");
    throw new TypeError("Wrong type");
    throw new RangeError("Out of range");
    throw new ReferenceError("Variable not defined");
    
    // Custom errors
    class CustomError extends Error {
      constructor(message) {
        super(message);
        this.name = "CustomError";
      }
    }
    throw new CustomError("Custom error message");
    
    // Error object properties
    error.name;                     // Error name
    error.message;                  // Error message
    error.stack;                    // Stack trace
    
    // Catching specific errors
    try {
      riskyOperation();
    } catch (error) {
      if (error instanceof TypeError) {
        console.error("Type error occurred");
      } else if (error instanceof RangeError) {
        console.error("Range error occurred");
      } else {
        console.error("Unknown error:", error);
      }
    }
    
    // Async error handling
    async function fetchData() {
      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }
        return await response.json();
      } catch (error) {
        console.error("Fetch error:", error);
        throw error;
      }
    }
    
    // Promise error handling
    promise
      .then(result => processResult(result))
      .catch(error => console.error("Promise error:", error))
      .finally(() => console.log("Done"));
    
    // Global error handling
    window.addEventListener('error', (event) => {
      console.error('Global error:', event.error);
    });
    
    window.addEventListener('unhandledrejection', (event) => {
      console.error('Unhandled promise rejection:', event.reason);
    });
    JavaScript

    Classes

    // Class declaration
    class Person {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
    
      greet() {
        return `Hello, I'm ${this.name}`;
      }
    
      static species() {
        return "Homo sapiens";
      }
    }
    
    // Creating instances
    const john = new Person("John", 30);
    john.greet();                   // "Hello, I'm John"
    Person.species();               // "Homo sapiens"
    
    // Inheritance
    class Employee extends Person {
      constructor(name, age, jobTitle) {
        super(name, age);           // Call parent constructor
        this.jobTitle = jobTitle;
      }
    
      describe() {
        return `${this.greet()} and I'm a ${this.jobTitle}`;
      }
    }
    
    const jane = new Employee("Jane", 28, "Developer");
    jane.describe();                // "Hello, I'm Jane and I'm a Developer"
    
    // Getters and setters
    class Circle {
      constructor(radius) {
        this._radius = radius;
      }
    
      get radius() {
        return this._radius;
      }
    
      set radius(value) {
        if (value <= 0) {
          throw new Error("Radius must be positive");
        }
        this._radius = value;
      }
    
      get area() {
        return Math.PI * this._radius ** 2;
      }
    }
    
    // Private fields (ES2022)
    class BankAccount {
      #balance = 0;                 // Private field
    
      deposit(amount) {
        this.#balance += amount;
      }
    
      getBalance() {
        return this.#balance;
      }
    }
    
    // Static members
    class MathUtils {
      static PI = 3.14159;
    
      static circleArea(radius) {
        return this.PI * radius ** 2;
      }
    }
    MathUtils.circleArea(5);
    
    // Class expressions
    const MyClass = class {
      constructor(name) {
        this.name = name;
      }
    };
    
    // Method overriding
    class Animal {
      speak() {
        return "Some sound";
      }
    }
    
    class Dog extends Animal {
      speak() {
        return "Woof!";
      }
    }
    JavaScript

    Modules

    // Exporting (math.js)
    export const PI = 3.14159;
    export function add(a, b) {
      return a + b;
    }
    export class Calculator {}
    
    // Default export
    export default function subtract(a, b) {
      return a - b;
    }
    
    // Named exports (alternative)
    const multiply = (a, b) => a * b;
    const divide = (a, b) => a / b;
    export { multiply, divide };
    
    // Export with rename
    export { multiply as mult, divide as div };
    
    // Importing
    import subtract from './math.js';
    import { PI, add } from './math.js';
    import { multiply as mult } from './math.js';
    import * as math from './math.js';
    
    // Import and export
    export { add } from './math.js';
    export * from './math.js';
    
    // Dynamic imports
    import('./math.js').then(module => {
      console.log(module.PI);
    });
    
    // Async dynamic import
    async function loadModule() {
      const module = await import('./math.js');
      console.log(module.PI);
    }
    JavaScript

    Common Array Methods

    const arr = [1, 2, 3, 4, 5];
    
    // Transformation
    arr.map(x => x * 2);            // [2, 4, 6, 8, 10]
    arr.filter(x => x > 2);         // [3, 4, 5]
    arr.reduce((sum, x) => sum + x, 0); // 15
    arr.flatMap(x => [x, x * 2]);   // [1, 2, 2, 4, 3, 6, ...]
    
    // Searching
    arr.find(x => x > 2);           // 3
    arr.findIndex(x => x > 2);      // 2
    arr.indexOf(3);                 // 2
    arr.includes(3);                // true
    
    // Testing
    arr.every(x => x > 0);          // true
    arr.some(x => x > 4);           // true
    
    // Iteration
    arr.forEach((item, index) => console.log(item));
    
    // Sorting
    arr.sort((a, b) => a - b);      // Ascending
    arr.sort((a, b) => b - a);      // Descending
    
    // Modifying
    arr.push(6);                    // Add to end
    arr.pop();                      // Remove from end
    arr.unshift(0);                 // Add to start
    arr.shift();                    // Remove from start
    arr.splice(2, 1, 99);           // Remove/add at index
    
    // Combining
    arr.concat([6, 7]);             // Combine arrays
    arr.join(', ');                 // Array to string
    arr.slice(1, 3);                // Extract portion
    
    // Other
    arr.reverse();                  // Reverse order
    arr.fill(0);                    // Fill with value
    Array.from('hello');            // Create from iterable
    Array.of(1, 2, 3);              // Create from arguments
    JavaScript

    Common String Methods

    const str = "Hello World";
    
    // Searching
    str.charAt(0);                  // "H"
    str.charCodeAt(0);              // 72
    str.indexOf("o");               // 4
    str.lastIndexOf("o");           // 7
    str.includes("World");          // true
    str.startsWith("Hello");        // true
    str.endsWith("World");          // true
    str.search(/world/i);           // 6
    
    // Extracting
    str.slice(0, 5);                // "Hello"
    str.substring(6, 11);           // "World"
    str.substr(6, 5);               // "World" (deprecated)
    
    // Modifying
    str.replace("World", "JS");     // "Hello JS"
    str.replaceAll("o", "0");       // "Hell0 W0rld"
    str.toUpperCase();              // "HELLO WORLD"
    str.toLowerCase();              // "hello world"
    str.trim();                     // Remove whitespace
    str.trimStart();                // Remove leading whitespace
    str.trimEnd();                  // Remove trailing whitespace
    str.padStart(15, "*");          // "****Hello World"
    str.padEnd(15, "*");            // "Hello World****"
    str.repeat(2);                  // "Hello WorldHello World"
    
    // Splitting
    str.split(" ");                 // ["Hello", "World"]
    str.split("");                  // ["H", "e", "l", ...]
    
    // Other
    str.length;                     // 11
    str.concat(" ", "JS");          // "Hello World JS"
    str.match(/o/g);                // ["o", "o"]
    str.matchAll(/o/g);             // Iterator
    JavaScript

    Common Object Methods

    const obj = {a: 1, b: 2, c: 3};
    
    // Keys, values, entries
    Object.keys(obj);               // ["a", "b", "c"]
    Object.values(obj);             // [1, 2, 3]
    Object.entries(obj);            // [["a", 1], ["b", 2], ["c", 3]]
    
    // Creating/copying
    Object.assign({}, obj);         // Shallow copy
    Object.create(proto);           // Create with prototype
    {...obj};                       // Spread (shallow copy)
    
    // Freezing/sealing
    Object.freeze(obj);             // Make immutable
    Object.seal(obj);               // Prevent add/remove properties
    Object.preventExtensions(obj);  // Prevent adding properties
    Object.isFrozen(obj);           // Check if frozen
    Object.isSealed(obj);           // Check if sealed
    Object.isExtensible(obj);       // Check if extensible
    
    // Property descriptors
    Object.getOwnPropertyDescriptor(obj, 'a');
    Object.getOwnPropertyDescriptors(obj);
    Object.defineProperty(obj, 'prop', {
      value: 42,
      writable: false,
      enumerable: true,
      configurable: false
    });
    Object.defineProperties(obj, {
      prop1: { value: 1 },
      prop2: { value: 2 }
    });
    
    // Prototype
    Object.getPrototypeOf(obj);
    Object.setPrototypeOf(obj, proto);
    
    // Other
    Object.hasOwn(obj, 'a');        // Check property (ES2022)
    obj.hasOwnProperty('a');        // Check property (older)
    'a' in obj;                     // Check property (includes inherited)
    Object.getOwnPropertyNames(obj); // All properties
    Object.getOwnPropertySymbols(obj); // Symbol properties
    Object.is(obj1, obj2);          // Same value comparison
    JavaScript

    Date & Time

    // Creating dates
    const now = new Date();
    const specific = new Date('2024-12-14');
    const fromParts = new Date(2024, 11, 14, 10, 30, 0); // Month is 0-indexed
    const fromTimestamp = new Date(1702555200000);
    
    // Getting components
    now.getFullYear();              // 2024
    now.getMonth();                 // 0-11 (0 = January)
    now.getDate();                  // 1-31
    now.getDay();                   // 0-6 (0 = Sunday)
    now.getHours();                 // 0-23
    now.getMinutes();               // 0-59
    now.getSeconds();               // 0-59
    now.getMilliseconds();          // 0-999
    now.getTime();                  // Timestamp (milliseconds)
    
    // UTC methods
    now.getUTCFullYear();
    now.getUTCMonth();
    now.getUTCDate();
    now.getUTCHours();
    
    // Setting components
    now.setFullYear(2025);
    now.setMonth(5);                // June
    now.setDate(15);
    now.setHours(14);
    now.setMinutes(30);
    now.setSeconds(45);
    now.setMilliseconds(500);
    now.setTime(1702555200000);
    
    // Formatting
    now.toString();                 // Full date string
    now.toDateString();             // Date only
    now.toTimeString();             // Time only
    now.toISOString();              // ISO 8601 format
    now.toLocaleDateString();       // Localized date
    now.toLocaleTimeString();       // Localized time
    now.toLocaleString();           // Localized date and time
    now.toUTCString();              // UTC string
    
    // Date arithmetic
    const tomorrow = new Date(now.getTime() + 24 * 60 * 60 * 1000);
    const diff = date2 - date1;     // Difference in milliseconds
    
    // Static methods
    Date.now();                     // Current timestamp
    Date.parse('2024-12-14');       // Parse string to timestamp
    Date.UTC(2024, 11, 14);         // UTC timestamp
    
    // Intl.DateTimeFormat
    const formatter = new Intl.DateTimeFormat('en-US', {
      year: 'numeric',
      month: 'long',
      day: 'numeric'
    });
    formatter.format(now);          // "December 14, 2024"
    JavaScript

    Regular Expressions

    // Creating regex
    const regex1 = /pattern/flags;
    const regex2 = new RegExp('pattern', 'flags');
    
    // Flags
    // g - global (find all matches)
    // i - case-insensitive
    // m - multiline
    // s - dotAll (. matches newlines)
    // u - unicode
    // y - sticky
    
    // Testing
    /hello/i.test('Hello World');   // true
    
    // Matching
    'Hello World'.match(/o/g);      // ["o", "o"]
    'Hello World'.matchAll(/o/gi);  // Iterator of matches
    
    // Searching
    'Hello World'.search(/world/i); // 6 (index)
    
    // Replacing
    'Hello World'.replace(/o/g, '0'); // "Hell0 W0rld"
    'Hello World'.replaceAll(/o/g, '0'); // "Hell0 W0rld"
    
    // Splitting
    'a,b,c'.split(/,/);             // ["a", "b", "c"]
    
    // Regex methods
    const regex = /(\d{3})-(\d{3})-(\d{4})/;
    regex.test('123-456-7890');     // true
    regex.exec('123-456-7890');     // Match object with groups
    
    // Common patterns
    /\d/                            // Digit
    /\D/                            // Non-digit
    /\w/                            // Word character (a-z, A-Z, 0-9, _)
    /\W/                            // Non-word character
    /\s/                            // Whitespace
    /\S/                            // Non-whitespace
    /./                             // Any character (except newline)
    /^/                             // Start of string
    /$/                             // End of string
    /\b/                            // Word boundary
    /\B/                            // Non-word boundary
    
    // Quantifiers
    /a*/                            // 0 or more
    /a+/                            // 1 or more
    /a?/                            // 0 or 1
    /a{3}/                          // Exactly 3
    /a{3,}/                         // 3 or more
    /a{3,5}/                        // 3 to 5
    
    // Character classes
    /[abc]/                         // a, b, or c
    /[^abc]/                        // Not a, b, or c
    /[a-z]/                         // Any lowercase letter
    /[A-Z]/                         // Any uppercase letter
    /[0-9]/                         // Any digit
    
    // Groups
    /(abc)/                         // Capturing group
    /(?:abc)/                       // Non-capturing group
    /(?<name>abc)/                  // Named capturing group
    /a|b/                           // Alternative (a or b)
    
    // Lookahead/Lookbehind
    /a(?=b)/                        // Positive lookahead
    /a(?!b)/                        // Negative lookahead
    /(?<=b)a/                       // Positive lookbehind
    /(?<!b)a/                       // Negative lookbehind
    
    // Examples
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    const phoneRegex = /^\d{3}-\d{3}-\d{4}$/;
    const urlRegex = /^https?:\/\/.+/;
    const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
    JavaScript

    JSON

    // JSON.stringify - Convert to JSON string
    const obj = {name: "John", age: 30};
    const json = JSON.stringify(obj);
    // '{"name":"John","age":30}'
    
    // With formatting
    JSON.stringify(obj, null, 2);   // Pretty print with 2 spaces
    
    // With replacer function
    JSON.stringify(obj, (key, value) => {
      if (typeof value === 'string') {
        return value.toUpperCase();
      }
      return value;
    });
    
    // With replacer array (include only specific keys)
    JSON.stringify(obj, ['name']);  // '{"name":"John"}'
    
    // JSON.parse - Parse JSON string
    const parsed = JSON.parse('{"name":"John","age":30}');
    
    // With reviver function
    JSON.parse('{"date":"2024-12-14"}', (key, value) => {
      if (key === 'date') {
        return new Date(value);
      }
      return value;
    });
    
    // Error handling
    try {
      const data = JSON.parse(jsonString);
    } catch (error) {
      console.error('Invalid JSON:', error);
    }
    
    // Working with complex objects
    const complex = {
      name: "John",
      birthDate: new Date(),
      greet: function() { return "Hello"; },
      symbol: Symbol('id'),
      undef: undefined
    };
    JSON.stringify(complex);
    // Functions, symbols, and undefined are omitted
    
    // Custom toJSON method
    class Person {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
    
      toJSON() {
        return {
          name: this.name,
          age: this.age,
          type: 'Person'
        };
      }
    }
    JavaScript

    Storage

    // localStorage (persistent)
    localStorage.setItem('key', 'value');
    localStorage.getItem('key');
    localStorage.removeItem('key');
    localStorage.clear();
    localStorage.length;
    localStorage.key(0);            // Get key by index
    
    // Storing objects
    const obj = {name: "John", age: 30};
    localStorage.setItem('user', JSON.stringify(obj));
    const user = JSON.parse(localStorage.getItem('user'));
    
    // sessionStorage (cleared when browser closes)
    sessionStorage.setItem('key', 'value');
    sessionStorage.getItem('key');
    sessionStorage.removeItem('key');
    sessionStorage.clear();
    
    // Storage event (triggered in other tabs)
    window.addEventListener('storage', (e) => {
      console.log('Key:', e.key);
      console.log('Old value:', e.oldValue);
      console.log('New value:', e.newValue);
      console.log('URL:', e.url);
    });
    
    // Cookies
    document.cookie = "username=John";
    document.cookie = "username=John; expires=Fri, 31 Dec 2024 23:59:59 GMT";
    document.cookie = "username=John; path=/; domain=example.com; secure; SameSite=Strict";
    
    // Reading cookies
    const cookies = document.cookie.split(';')
      .map(c => c.trim())
      .reduce((acc, cookie) => {
        const [key, value] = cookie.split('=');
        acc[key] = value;
        return acc;
      }, {});
    
    // Deleting cookie
    document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
    JavaScript

    Fetch API

    // Basic GET request
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => console.log(data))
      .catch(error => console.error('Error:', error));
    
    // With async/await
    async function getData() {
      try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        return data;
      } catch (error) {
        console.error('Error:', error);
      }
    }
    
    // POST request
    fetch('https://api.example.com/data', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name: 'John',
        age: 30
      })
    })
      .then(response => response.json())
      .then(data => console.log(data));
    
    // PUT request
    fetch('https://api.example.com/data/1', {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name: 'John Updated',
        age: 31
      })
    });
    
    // DELETE request
    fetch('https://api.example.com/data/1', {
      method: 'DELETE'
    });
    
    // With custom headers
    fetch(url, {
      headers: {
        'Authorization': 'Bearer token123',
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      }
    });
    
    // Checking response status
    async function fetchData() {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      return await response.json();
    }
    
    // Different response types
    response.json()                 // Parse as JSON
    response.text()                 // Get as text
    response.blob()                 // Get as Blob
    response.arrayBuffer()          // Get as ArrayBuffer
    response.formData()             // Get as FormData
    
    // Response properties
    response.ok                     // true if status 200-299
    response.status                 // HTTP status code
    response.statusText             // Status message
    response.headers                // Headers object
    response.url                    // Final URL
    
    // Abort request
    const controller = new AbortController();
    const signal = controller.signal;
    
    fetch(url, { signal })
      .then(response => response.json())
      .catch(error => {
        if (error.name === 'AbortError') {
          console.log('Fetch aborted');
        }
      });
    
    // Abort after 5 seconds
    setTimeout(() => controller.abort(), 5000);
    
    // Upload file
    const formData = new FormData();
    formData.append('file', fileInput.files[0]);
    
    fetch(url, {
      method: 'POST',
      body: formData
    });
    
    // Multiple requests
    const [data1, data2, data3] = await Promise.all([
      fetch(url1).then(r => r.json()),
      fetch(url2).then(r => r.json()),
      fetch(url3).then(r => r.json())
    ]);
    JavaScript

    Additional Tips

    // Console methods
    console.log('Log message');
    console.error('Error message');
    console.warn('Warning message');
    console.info('Info message');
    console.table([{a: 1, b: 2}, {a: 3, b: 4}]);
    console.group('Group');
    console.groupEnd();
    console.time('Timer');
    console.timeEnd('Timer');
    console.clear();
    
    // Debugging
    debugger;                       // Breakpoint
    
    // Type conversion
    String(123)                     // "123"
    Number("123")                   // 123
    Boolean(1)                      // true
    parseInt("123")                 // 123
    parseFloat("123.45")            // 123.45
    
    // Math operations
    Math.abs(-5)                    // 5
    Math.ceil(4.3)                  // 5
    Math.floor(4.9)                 // 4
    Math.round(4.5)                 // 5
    Math.max(1, 2, 3)               // 3
    Math.min(1, 2, 3)               // 1
    Math.pow(2, 3)                  // 8
    Math.sqrt(16)                   // 4
    Math.random()                   // 0 to 1
    Math.PI                         // 3.141592653589793
    
    // Timers
    setTimeout(() => console.log('Delayed'), 1000);
    const intervalId = setInterval(() => console.log('Repeated'), 1000);
    clearInterval(intervalId);
    clearTimeout(timeoutId);
    
    // Window/global methods
    alert('Message');
    confirm('Are you sure?');
    prompt('Enter name:');
    
    // Encoding
    encodeURI('https://example.com/path with spaces');
    decodeURI('https://example.com/path%20with%20spaces');
    encodeURIComponent('value with special chars');
    decodeURIComponent('value%20with%20special%20chars');
    btoa('Hello')                   // Base64 encode
    atob('SGVsbG8=')                // Base64 decode
    JavaScript

    End of Cheatsheet


    Discover more from Altgr Blog

    Subscribe to get the latest posts sent to your email.

    Leave a Reply

    Your email address will not be published. Required fields are marked *