JavaScript Master Guide in web devlopment

Complete JavaScript Master Guide

Complete JavaScript Guide

From absolute beginner to advanced concepts. Interactive examples, live coding, and comprehensive coverage.

Learning Progress: 0%

📚 JavaScript Basics

#️⃣ Variables & Data Types

JavaScript has three ways to declare variables: var, let, and const.

// Variable Declaration
let name = "John";      // String
const age = 25;         // Number (constant)
var isStudent = true;   // Boolean (old way)

// Data Types
let string = "Hello";
let number = 42;
let boolean = true;
let array = [1, 2, 3];
let object = {key: "value"};
let nullValue = null;
let undefinedValue;
let symbol = Symbol('id');

console.log(typeof string); // "string"
console.log(typeof number); // "number"

➕➖ Operators

JavaScript supports arithmetic, comparison, logical, and assignment operators.

// Arithmetic Operators
let sum = 10 + 5;       // 15
let difference = 10 - 5; // 5
let product = 10 * 5;   // 50
let quotient = 10 / 5;  // 2
let remainder = 10 % 3; // 1
let exponent = 2 ** 3;  // 8

// Comparison Operators
console.log(5 == "5");   // true (loose equality)
console.log(5 === "5");  // false (strict equality)
console.log(5 != "5");   // false
console.log(5 !== "5");  // true

// Logical Operators
let and = true && false; // false
let or = true || false;  // true
let not = !true;         // false

// Ternary Operator
let result = age >= 18 ? "Adult" : "Minor";

🔄 Control Flow

Control the flow of your program with conditionals and loops.

// If-Else Statement
let score = 85;

if (score >= 90) {
    console.log("A Grade");
} else if (score >= 80) {
    console.log("B Grade"); // This executes
} else {
    console.log("C Grade");
}

// Switch Statement
let day = "Monday";

switch(day) {
    case "Monday":
        console.log("Start of week");
        break;
    case "Friday":
        console.log("Weekend is near");
        break;
    default:
        console.log("Regular day");
}

// Loops
// For loop
for (let i = 0; i < 5; i++) {
    console.log(i); // 0,1,2,3,4
}

// While loop
let count = 0;
while (count < 3) {
    console.log(count);
    count++;
}

// Do-While loop
do {
    console.log("Runs at least once");
} while (false);

🚀 Intermediate JavaScript

📦 Arrays & Methods

Arrays are ordered collections with powerful built-in methods.

// Array Creation
let fruits = ["Apple", "Banana", "Orange"];

// Common Array Methods
fruits.push("Mango");          // Add to end
fruits.pop();                  // Remove from end
fruits.unshift("Strawberry");  // Add to beginning
fruits.shift();                // Remove from beginning

// Array Transformation
let numbers = [1, 2, 3, 4, 5];

// Map: Transform each element
let doubled = numbers.map(n => n * 2); // [2,4,6,8,10]

// Filter: Select elements
let evens = numbers.filter(n => n % 2 === 0); // [2,4]

// Reduce: Accumulate values
let sum = numbers.reduce((acc, n) => acc + n, 0); // 15

// Find elements
let found = numbers.find(n => n > 3); // 4
let index = numbers.findIndex(n => n === 3); // 2

// Check conditions
let allPositive = numbers.every(n => n > 0); // true
let hasEven = numbers.some(n => n % 2 === 0); // true

// Iteration
numbers.forEach((n, i) => {
    console.log(`Index ${i}: ${n}`);
});

🗺️ Objects & Methods

Objects are key-value pairs that can store complex data.

// Object Creation
let person = {
    firstName: "John",
    lastName: "Doe",
    age: 30,
    hobbies: ["reading", "coding"],
    
    // Method
    fullName() {
        return `${this.firstName} ${this.lastName}`;
    },
    
    // Getter
    get birthYear() {
        return new Date().getFullYear() - this.age;
    }
};

// Accessing Properties
console.log(person.firstName);      // Dot notation
console.log(person["lastName"]);    // Bracket notation
console.log(person.fullName());     // Method call
console.log(person.birthYear);      // Getter

// Adding/Modifying Properties
person.email = "john@example.com";
person.age = 31;

// Deleting Properties
delete person.hobbies;

// Object Methods
let keys = Object.keys(person);     // ["firstName", "lastName"...]
let values = Object.values(person); // ["John", "Doe"...]
let entries = Object.entries(person); // [["firstName","John"]...]

// Object Destructuring
let { firstName, age } = person;
console.log(firstName, age); // John 31

// Spread Operator
let personCopy = { ...person };
let merged = { ...person, city: "New York" };

🎯 Functions

Functions are reusable blocks of code that perform specific tasks.

// Function Declaration
function greet(name) {
    return `Hello, ${name}!`;
}

// Function Expression
const greet2 = function(name) {
    return `Hi, ${name}!`;
};

// Arrow Function
const greet3 = (name) => `Hey, ${name}!`;

// Default Parameters
function multiply(a, b = 1) {
    return a * b;
}

// Rest Parameters
function sumAll(...numbers) {
    return numbers.reduce((acc, n) => acc + n, 0);
}

// Higher-Order Functions
function createMultiplier(multiplier) {
    return function(number) {
        return number * multiplier;
    };
}

const double = createMultiplier(2);
console.log(double(5)); // 10

// Callback Functions
function processUserInput(callback) {
    let name = "Alice";
    callback(name);
}

processUserInput(function(name) {
    console.log(`Processing ${name}`);
});

// Immediately Invoked Function Expression (IIFE)
(function() {
    console.log("IIFE executed immediately!");
})();

🎯 Advanced JavaScript

🔗 Closures & Scope

Understanding scope and closures is crucial for advanced JavaScript programming.

// Lexical Scoping
function outer() {
    let outerVar = "I'm outside!";
    
    function inner() {
        let innerVar = "I'm inside!";
        console.log(outerVar); // Can access outerVar
    }
    
    inner();
    // console.log(innerVar); // Error: innerVar not accessible
}

// Closure Example
function createCounter() {
    let count = 0; // Private variable
    
    return {
        increment: function() {
            count++;
            return count;
        },
        decrement: function() {
            count--;
            return count;
        },
        getCount: function() {
            return count;
        }
    };
}

const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getCount());  // 2

// Module Pattern
const Calculator = (function() {
    let memory = 0;
    
    function add(a, b) {
        return a + b;
    }
    
    function store(value) {
        memory = value;
    }
    
    return {
        add: add,
        store: store,
        getMemory: () => memory
    };
})();

// Scope Chain
let globalVar = "global";

function first() {
    let firstVar = "first";
    
    function second() {
        let secondVar = "second";
        console.log(globalVar); // Accessible
        console.log(firstVar);  // Accessible
        console.log(secondVar); // Accessible
    }
    
    second();
}

first();

🔄 Prototypes & Inheritance

JavaScript uses prototype-based inheritance rather than classical inheritance.

// Constructor Function
function Person(name, age) {
    this.name = name;
    this.age = age;
}

// Adding method to prototype
Person.prototype.greet = function() {
    return `Hello, I'm ${this.name}`;
};

// Creating instances
const john = new Person("John", 30);
console.log(john.greet()); // Hello, I'm John

// Prototype Chain
console.log(john.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true

// Inheritance using Prototypes
function Student(name, age, grade) {
    Person.call(this, name, age);
    this.grade = grade;
}

// Set up prototype chain
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

// Add student-specific method
Student.prototype.study = function() {
    return `${this.name} is studying`;
};

const alice = new Student("Alice", 20, "A");
console.log(alice.greet()); // Inherited from Person
console.log(alice.study()); // Student method

// Checking relationships
console.log(alice instanceof Student); // true
console.log(alice instanceof Person);  // true
console.log(alice instanceof Object);  // true

This Keyword

The value of this depends on how a function is called.

// Global context
console.log(this); // Window (browser) / Global (Node.js)

// Function context
function regularFunction() {
    console.log(this); // Window/Global (in non-strict mode)
}

// Method context
const obj = {
    name: "Object",
    method: function() {
        console.log(this.name); // "Object"
    }
};

// Constructor context
function Car(make) {
    this.make = make;
    console.log(this); // New Car instance
}

const car = new Car("Toyota");

// Arrow function context
const arrowObj = {
    name: "Arrow Object",
    regularMethod: function() {
        console.log(this.name); // "Arrow Object"
        
        const arrowFunc = () => {
            console.log(this.name); // "Arrow Object" (inherits from parent)
        };
        arrowFunc();
    }
};

// Event handler context
button.addEventListener('click', function() {
    console.log(this); // The button element
});

// Explicit binding
function showInfo(greeting) {
    console.log(`${greeting}, ${this.name}`);
}

const user = { name: "Bob" };

showInfo.call(user, "Hello");       // Hello, Bob
showInfo.apply(user, ["Hi"]);       // Hi, Bob
const boundFunc = showInfo.bind(user);
boundFunc("Hey");                   // Hey, Bob

🌐 DOM Manipulation

🎯 Selecting Elements

Learn how to select and manipulate DOM elements.

// Selecting Single Elements
const byId = document.getElementById('myId');
const byClass = document.querySelector('.myClass');
const byTag = document.querySelector('div');
const byAttribute = document.querySelector('[data-custom]');

// Selecting Multiple Elements
const allByClass = document.getElementsByClassName('item');
const allByTag = document.getElementsByTagName('p');
const allByQuery = document.querySelectorAll('.container div');

// Traversing DOM
const parent = element.parentNode;
const children = element.children;
const firstChild = element.firstElementChild;
const lastChild = element.lastElementChild;
const nextSibling = element.nextElementSibling;
const prevSibling = element.previousElementSibling;

// Checking Relationships
const contains = parent.contains(child);
const matches = element.matches('.selector');

// Live vs Static Collections
const live = document.getElementsByClassName('item'); // Live
const static = document.querySelectorAll('.item');     // Static

Modifying Elements

Create, modify, and remove DOM elements dynamically.

// Creating Elements
const newDiv = document.createElement('div');
const newText = document.createTextNode('Hello World');

// Setting Attributes
newDiv.id = 'myDiv';
newDiv.className = 'container active';
newDiv.setAttribute('data-custom', 'value');
newDiv.style.color = 'red';
newDiv.style.backgroundColor = '#f0f0f0';

// Adding Content
newDiv.textContent = 'Plain Text';
newDiv.innerHTML = 'HTML Content';

// Appending Elements
document.body.appendChild(newDiv);
parentElement.append(newDiv, anotherElement);
parentElement.prepend(newDiv); // Add as first child
existingElement.before(newDiv); // Insert before
existingElement.after(newDiv);  // Insert after

// Removing Elements
parentElement.removeChild(childElement);
childElement.remove(); // Modern way

// Replacing Elements
parentElement.replaceChild(newElement, oldElement);

// Cloning Elements
const clone = element.cloneNode(true); // Deep clone

// Class Operations
element.classList.add('new-class');
element.classList.remove('old-class');
element.classList.toggle('active');
element.classList.contains('check');
element.classList.replace('old', 'new');

🎮 Events & Event Delegation

Handle user interactions with event listeners and delegation.

// Adding Event Listeners
button.addEventListener('click', function(event) {
    console.log('Button clicked!');
    console.log(event.target); // The clicked element
    console.log(event.currentTarget); // The element with listener
});

// Event Object Properties
function handleEvent(event) {
    event.preventDefault(); // Prevent default behavior
    event.stopPropagation(); // Stop bubbling
    
    console.log(event.type); // Event type
    console.log(event.clientX, event.clientY); // Mouse position
    console.log(event.key); // Key pressed
}

// Event Phases
// 1. Capture Phase (top to target)
// 2. Target Phase
// 3. Bubbling Phase (target to top)

// Event Delegation
document.getElementById('list').addEventListener('click', function(event) {
    if (event.target.matches('li.item')) {
        console.log('List item clicked:', event.target.textContent);
    }
});

// Common Events
element.addEventListener('click', handler);
element.addEventListener('dblclick', handler);
element.addEventListener('mouseenter', handler);
element.addEventListener('mouseleave', handler);
element.addEventListener('mousemove', handler);
element.addEventListener('keydown', handler);
element.addEventListener('keyup', handler);
element.addEventListener('submit', handler);
element.addEventListener('change', handler);
element.addEventListener('input', handler);
element.addEventListener('focus', handler);
element.addEventListener('blur', handler);

// Custom Events
const customEvent = new CustomEvent('myevent', {
    detail: { message: 'Custom event fired!' },
    bubbles: true,
    cancelable: true
});

element.dispatchEvent(customEvent);

⚡ Asynchronous JavaScript

⏱️ Callbacks

The original way to handle asynchronous operations in JavaScript.

// Basic Callback Example
function fetchData(callback) {
    setTimeout(() => {
        const data = { id: 1, name: "John" };
        callback(null, data); // Node.js convention: error first
    }, 1000);
}

// Using Callback
fetchData(function(error, data) {
    if (error) {
        console.error("Error:", error);
    } else {
        console.log("Data:", data);
    }
});

// Callback Hell (Pyramid of Doom)
getUser(function(user) {
    getPosts(user.id, function(posts) {
        getComments(posts[0].id, function(comments) {
            getLikes(comments[0].id, function(likes) {
                console.log(likes);
            });
        });
    });
});

// Error Handling with Callbacks
function asyncOperation(callback) {
    setTimeout(() => {
        try {
            // Simulate error
            if (Math.random() > 0.5) {
                throw new Error("Something went wrong");
            }
            const result = "Success";
            callback(null, result);
        } catch (error) {
            callback(error, null);
        }
    }, 500);
}

🤞 Promises

Promises provide a cleaner way to handle asynchronous operations.

// Creating a Promise
const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        const success = Math.random() > 0.3;
        
        if (success) {
            resolve("Operation successful!");
        } else {
            reject(new Error("Operation failed"));
        }
    }, 1000);
});

// Consuming a Promise
myPromise
    .then(result => {
        console.log("Success:", result);
        return result.toUpperCase();
    })
    .then(modifiedResult => {
        console.log("Modified:", modifiedResult);
    })
    .catch(error => {
        console.error("Error:", error.message);
    })
    .finally(() => {
        console.log("Operation completed");
    });

// Promise Static Methods
Promise.resolve("Immediate value"); // Creates resolved promise
Promise.reject(new Error("Failed")); // Creates rejected promise

// Promise.all - Wait for all promises
Promise.all([promise1, promise2, promise3])
    .then(results => {
        console.log("All completed:", results);
    })
    .catch(error => {
        console.error("One failed:", error);
    });

// Promise.race - First to settle wins
Promise.race([fastPromise, slowPromise])
    .then(result => {
        console.log("First to complete:", result);
    });

// Promise.allSettled - Wait for all to settle
Promise.allSettled([promise1, promise2])
    .then(results => {
        results.forEach(result => {
            if (result.status === 'fulfilled') {
                console.log("Success:", result.value);
            } else {
                console.log("Failed:", result.reason);
            }
        });
    });

// Promise.any - First to fulfill
Promise.any([promise1, promise2])
    .then(result => {
        console.log("First success:", result);
    })
    .catch(errors => {
        console.error("All failed:", errors);
    });

Async/Await

The modern way to write asynchronous code that looks synchronous.

// Async Function Declaration
async function fetchData() {
    try {
        // Await pauses execution until promise settles
        const response = await fetch('https://api.example.com/data');
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const data = await response.json();
        return data;
    } catch (error) {
        console.error("Fetch error:", error);
        throw error; // Re-throw for caller to handle
    }
}

// Using Async Functions
async function processData() {
    try {
        const user = await getUser();
        const posts = await getPosts(user.id);
        const comments = await getComments(posts[0].id);
        
        return { user, posts, comments };
    } catch (error) {
        console.error("Processing failed:", error);
        return null;
    }
}

// Parallel Execution
async function fetchAllData() {
    // Run promises in parallel
    const [users, posts, comments] = await Promise.all([
        fetchUsers(),
        fetchPosts(),
        fetchComments()
    ]);
    
    return { users, posts, comments };
}

// Async Iteration
async function processItems(items) {
    for (const item of items) {
        const result = await processItem(item);
        console.log(result);
    }
}

// Async Generators
async function* asyncGenerator() {
    let i = 0;
    while (i < 3) {
        await delay(1000);
        yield i++;
    }
}

// Using Async Generator
for await (const num of asyncGenerator()) {
    console.log(num);
}

// Top-level Await (ES2022)
const data = await fetchData();
console.log(data);

🧩 Object-Oriented Programming

🏗️ ES6 Classes

Syntactic sugar over JavaScript's existing prototype-based inheritance.

// Class Declaration
class Person {
    // Constructor
    constructor(name, age) {
        this.name = name;
        this.age = age;
        this.createdAt = new Date();
    }
    
    // Instance Method
    greet() {
        return `Hello, I'm ${this.name}`;
    }
    
    // Getter
    get birthYear() {
        return new Date().getFullYear() - this.age;
    }
    
    // Setter
    set nickname(value) {
        this._nickname = value;
    }
    
    // Static Method
    static compare(person1, person2) {
        return person1.age - person2.age;
    }
    
    // Private Field (ES2022)
    #secret = "This is private";
    
    // Private Method
    #logSecret() {
        console.log(this.#secret);
    }
}

// Creating Instances
const john = new Person("John", 30);
console.log(john.greet()); // Hello, I'm John
console.log(john.birthYear); // 1993
john.nickname = "Johnny";

// Inheritance
class Student extends Person {
    constructor(name, age, grade) {
        super(name, age); // Call parent constructor
        this.grade = grade;
    }
    
    // Method Overriding
    greet() {
        return `${super.greet()} and I'm a student`;
    }
    
    study() {
        return `${this.name} is studying`;
    }
}

const alice = new Student("Alice", 20, "A");
console.log(alice.greet()); // Hello, I'm Alice and I'm a student
console.log(alice.study()); // Alice is studying

// Static Properties
class MathUtils {
    static PI = 3.14159;
    
    static circleArea(radius) {
        return this.PI * radius * radius;
    }
}

console.log(MathUtils.circleArea(5)); // 78.53975

🎭 Polymorphism

Different classes can define methods with the same name.

// Base Class
class Animal {
    constructor(name) {
        this.name = name;
    }
    
    makeSound() {
        return "Some generic sound";
    }
    
    move() {
        return `${this.name} moves`;
    }
}

// Derived Classes
class Dog extends Animal {
    constructor(name, breed) {
        super(name);
        this.breed = breed;
    }
    
    // Method Overriding
    makeSound() {
        return "Woof! Woof!";
    }
    
    fetch() {
        return `${this.name} fetches the ball`;
    }
}

class Cat extends Animal {
    makeSound() {
        return "Meow!";
    }
    
    purr() {
        return `${this.name} purrs`;
    }
}

class Bird extends Animal {
    makeSound() {
        return "Chirp! Chirp!";
    }
    
    move() {
        return `${this.name} flies`;
    }
}

// Using Polymorphism
const animals = [
    new Dog("Buddy", "Golden Retriever"),
    new Cat("Whiskers"),
    new Bird("Tweety")
];

animals.forEach(animal => {
    console.log(animal.makeSound()); // Different sounds
    console.log(animal.move());      // Different movements
});

// Duck Typing
class Car {
    drive() {
        return "Car is driving";
    }
}

class Boat {
    drive() {
        return "Boat is sailing";
    }
}

function testDrive(vehicle) {
    console.log(vehicle.drive());
}

testDrive(new Car());  // Car is driving
testDrive(new Boat()); // Boat is sailing

📦 Encapsulation

Bundling data and methods together, hiding internal implementation.

// Using Closures for Encapsulation
function createBankAccount(initialBalance) {
    let balance = initialBalance; // Private variable
    
    return {
        deposit: function(amount) {
            if (amount > 0) {
                balance += amount;
                return `Deposited $${amount}. New balance: $${balance}`;
            }
            return "Invalid deposit amount";
        },
        
        withdraw: function(amount) {
            if (amount > 0 && amount <= balance) {
                balance -= amount;
                return `Withdrew $${amount}. New balance: $${balance}`;
            }
            return "Invalid withdrawal amount";
        },
        
        getBalance: function() {
            return `Current balance: $${balance}`;
        },
        
        // No direct access to balance variable
    };
}

const account = createBankAccount(1000);
console.log(account.getBalance()); // Current balance: $1000
console.log(account.deposit(500)); // Deposited $500. New balance: $1500
console.log(account.withdraw(200)); // Withdrew $200. New balance: $1300
// console.log(account.balance); // undefined

// Using ES6 Classes with Private Fields
class Temperature {
    #celsius = 0; // Private field
    
    constructor(celsius) {
        this.#celsius = celsius;
    }
    
    get celsius() {
        return this.#celsius;
    }
    
    set celsius(value) {
        if (value < -273.15) {
            throw new Error("Temperature below absolute zero");
        }
        this.#celsius = value;
    }
    
    get fahrenheit() {
        return this.#celsius * 1.8 + 32;
    }
    
    set fahrenheit(value) {
        this.#celsius = (value - 32) / 1.8;
    }
    
    #validateTemp(temp) { // Private method
        return temp >= -273.15;
    }
}

const temp = new Temperature(25);
console.log(temp.celsius);     // 25
console.log(temp.fahrenheit);  // 77
temp.celsius = 30;
// temp.#celsius = 100; // Error: Private field

💻 Practice JavaScript

Live JavaScript Editor

Output will appear here...

Quick Examples to Try:

🧪 JavaScript Challenges

Practice with these coding challenges:

Challenge 1: Palindrome Checker

Write a function that checks if a string is a palindrome.

Challenge 2: Array Flatten

Write a function that flattens a nested array.

📋 JavaScript Cheat Sheet

Array Methods

  • push() - Add to end
  • pop() - Remove from end
  • shift() - Remove from start
  • unshift() - Add to start
  • slice() - Copy portion
  • splice() - Remove/insert
  • concat() - Merge arrays
  • indexOf() - Find index
  • includes() - Check existence

String Methods

  • length - Get length
  • toUpperCase() - Convert case
  • toLowerCase() - Convert case
  • trim() - Remove whitespace
  • split() - String to array
  • join() - Array to string
  • slice() - Extract portion
  • replace() - Replace text
  • includes() - Check substring

Object Methods

  • Object.keys() - Get keys
  • Object.values() - Get values
  • Object.entries() - Get key-value pairs
  • Object.assign() - Copy properties
  • Object.freeze() - Prevent changes
  • Object.seal() - Prevent add/delete
  • hasOwnProperty() - Check property

Number Methods

  • toFixed() - Fixed decimal
  • toPrecision() - Format precision
  • toString() - Convert to string
  • parseInt() - String to int
  • parseFloat() - String to float
  • isNaN() - Check if NaN
  • isFinite() - Check if finite

Date Methods

  • new Date() - Current date
  • getFullYear() - Get year
  • getMonth() - Get month (0-11)
  • getDate() - Get day of month
  • getDay() - Get day of week
  • getHours() - Get hours
  • getMinutes() - Get minutes
  • getTime() - Get timestamp

Math Methods

  • Math.PI - Pi constant
  • Math.abs() - Absolute value
  • Math.round() - Round number
  • Math.floor() - Round down
  • Math.ceil() - Round up
  • Math.random() - Random number
  • Math.max() - Maximum value
  • Math.min() - Minimum value
  • Math.pow() - Power
  • Math.sqrt() - Square root

🚀 Modern JavaScript Features

ES6+ features that every developer should know:

// 1. Template Literals
const name = "John";
const greeting = `Hello, ${name}!`;

// 2. Destructuring
const [first, second] = [1, 2, 3];
const { age, city } = person;

// 3. Spread Operator
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];

const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 };

// 4. Rest Parameters
function sum(...numbers) {
    return numbers.reduce((acc, n) => acc + n, 0);
}

// 5. Default Parameters
function greet(name = "Guest") {
    return `Hello, ${name}`;
}

// 6. Arrow Functions
const add = (a, b) => a + b;

// 7. Optional Chaining (ES2020)
const street = user?.address?.street;

// 8. Nullish Coalescing (ES2020)
const value = input ?? "default";

// 9. Logical Assignment (ES2021)
a ||= b; // a = a || b
a &&= b; // a = a && b
a ??= b; // a = a ?? b

// 10. Promise.allSettled (ES2020)
const results = await Promise.allSettled(promises);

// 11. String.matchAll (ES2020)
const matches = str.matchAll(/pattern/g);

// 12. globalThis (ES2020)
console.log(globalThis === window); // Browser
console.log(globalThis === global); // Node.js

// 13. BigInt (ES2020)
const big = 123456789012345678901234567890n;

// 14. Dynamic Import
const module = await import('./module.js');

// 15. Top-level Await (ES2022)
const data = await fetchData();