JS Tutorial

Welcome to JavaScript! This tutorial introduces you to the fundamentals of JavaScript, the most widely used programming language for web development. You'll learn the basics, write your first scripts, and understand how JavaScript interacts with web pages.

Key Concepts

  • JavaScript as a client-side scripting language
  • Embedding JS in HTML
  • Basic syntax and statements
  • Variables and data types
  • Using the browser console for testing

JavaScript is a versatile language that can manipulate web page content, respond to user events, and communicate with servers. Unlike HTML and CSS, which define structure and style, JavaScript provides interactivity.

You can include JavaScript in your web pages in three ways: inline, internal, or external. Inline is rarely used due to maintainability issues. Internal scripts go inside a <script> tag within the HTML file, and external scripts are stored in separate .js files and linked to HTML.

JavaScript statements typically end with a semicolon, and the language is case-sensitive. The browser console is an excellent tool for testing snippets and debugging your code quickly.

Syntax / Code Snippets


// Basic JS syntax
console.log("Hello, JavaScript!");  // prints message to console
    
Example

// Display a message in the console
console.log("Welcome to LearnX JavaScript Course!");
    
Live Editor

Real-World Use Case / Mini-Project

Create a web page that greets users based on the current time of day:


let hour = new Date().getHours();
if(hour < 12) {
  console.log("Good Morning!");
} else if(hour < 18) {
  console.log("Good Afternoon!");
} else {
  console.log("Good Evening!");
}
    

Common Mistakes and Pitfalls

  • Forgetting semicolons (usually optional but can cause issues)
  • Using undeclared variables without let, const, or var
  • Case sensitivity errors (e.g., console.log vs Console.Log)

Best Practices

  • Always use let or const instead of var
  • Keep code readable with proper indentation
  • Use console.log() for debugging during development
  • Separate JS from HTML for maintainability

JS Syntax

JavaScript syntax defines the rules for writing valid code. Understanding syntax is crucial for creating functional scripts and avoiding errors. In this section, we'll go through statements, expressions, comments, and how JS interprets code.

Key Concepts

  • Statements and expressions
  • Semicolons and line breaks
  • Comments (single-line and multi-line)
  • Case sensitivity
  • Whitespace and indentation

JavaScript programs are made up of statements, which are instructions the browser executes. Statements often end with a semicolon, though JavaScript can sometimes infer it automatically. Expressions are pieces of code that produce a value.

Comments help document your code. Single-line comments start with // and multi-line comments are wrapped in /* ... */. Using proper comments is essential for readability and collaboration.

JavaScript is case-sensitive, so Variable and variable are different identifiers. Proper indentation and spacing improve readability and reduce errors, especially in larger scripts.

Syntax / Code Snippets


// Single-line comment
let message = "Hello JS";  // variable declaration

/*
 Multi-line comment
 explaining code
*/
console.log(message);
    
Example

// Using statements, expressions, and comments
let a = 10;           // variable declaration
let b = 20;           // variable declaration
let sum = a + b;      // expression: addition
console.log(sum);     // prints 30
    
Live Editor

Real-World Use Case / Mini-Project

Create a small calculator that adds two numbers inputted by the user (using prompt):


let num1 = Number(prompt("Enter first number:"));
let num2 = Number(prompt("Enter second number:"));
let total = num1 + num2;
console.log("The sum is: " + total);
    

Common Mistakes and Pitfalls

  • Omitting semicolons in places where they’re necessary
  • Using incorrect case for variable names
  • Confusing statements with expressions
  • Neglecting to close multi-line comments properly

Best Practices

  • Use semicolons consistently for clarity
  • Comment your code to explain logic
  • Use descriptive variable names
  • Maintain consistent indentation for readability

JS Variables

Variables are containers for storing data values in JavaScript. They allow you to reference, manipulate, and update information throughout your program. Understanding variables is essential for writing dynamic and interactive scripts.

Key Concepts

  • Declaring variables with let, const, and var
  • Variable naming rules
  • Data types and type inference
  • Scope: global vs local variables
  • Mutable vs immutable variables

In modern JavaScript, let and const are preferred over var. Use let for variables that may change, and const for constants that remain fixed. var is function-scoped and generally avoided in ES6+ code.

Variables must begin with a letter, underscore, or dollar sign. They cannot start with numbers or include spaces. JavaScript is case-sensitive, so myVar and myvar are different.

Understanding scope is important. Global variables are accessible anywhere, while local variables exist only within their block or function.

Syntax / Code Snippets


// Variable declarations
let name = "LearnX";    // mutable
const pi = 3.1416;      // immutable
var oldVar = "legacy";  // function-scoped
    
Example

// Using variables
let firstName = "John";
let age = 25;
const country = "India";

console.log(firstName + " is " + age + " years old from " + country);
    
Live Editor

Real-World Use Case / Mini-Project

Create a simple user profile that stores name, age, and hobbies, and logs a summary:


let userName = prompt("Enter your name:");
let userAge = Number(prompt("Enter your age:"));
let userHobby = prompt("Enter your favorite hobby:");

console.log(userName + " is " + userAge + " years old and enjoys " + userHobby + ".");
    

Common Mistakes and Pitfalls

  • Using var unnecessarily in modern JS
  • Reassigning const variables
  • Invalid variable names (starting with numbers or symbols)
  • Confusing global and local scope

Best Practices

  • Prefer let and const over var
  • Name variables descriptively
  • Keep constants in UPPERCASE for readability
  • Limit the use of global variables to reduce bugs

JS Operators

Operators in JavaScript are symbols used to perform operations on variables and values. They are the building blocks for calculations, comparisons, and logic in your programs.

Key Concepts

  • Arithmetic operators: +, -, *, /, %
  • Assignment operators: =, +=, -=
  • Comparison operators: ==, ===, <, >
  • Logical operators: &&, ||, !
  • Increment and decrement: ++, --

Arithmetic operators perform mathematical operations on numbers. Assignment operators assign values to variables, often combined with arithmetic (e.g., x += 5 adds 5 to x).

Comparison operators evaluate relationships between values and return true or false. Logical operators combine multiple conditions for decision making. Increment (++) and decrement (--) operators are shorthand for adding or subtracting 1.

Understanding operator precedence is important, as some operators execute before others. Use parentheses to control the order of operations for clarity.

Syntax / Code Snippets


// Arithmetic operators
let a = 10, b = 3;
console.log(a + b); // 13
console.log(a % b); // 1

// Assignment operators
let x = 5;
x += 3; // x = 8

// Comparison
console.log(a > b); // true

// Logical
console.log(a > 5 && b < 5); // true
    
Example

// Using different operators
let price = 100;
let tax = 0.1;

let total = price + (price * tax); // arithmetic
console.log("Total Price:", total);

let isExpensive = total > 105; // comparison
console.log("Is the item expensive?", isExpensive);

let discountApplied = true;
console.log("Eligible for offer?", isExpensive && discountApplied); // logical
    
Live Editor

Real-World Use Case / Mini-Project

Create a simple shopping cart calculator that applies discount if the total exceeds a threshold:


let item1 = 50;
let item2 = 60;
let totalPrice = item1 + item2;

let discount = totalPrice > 100 ? 10 : 0; // ternary operator
totalPrice -= discount;

console.log("Final Total:", totalPrice);
    

Common Mistakes and Pitfalls

  • Confusing == and ===
  • Misplacing parentheses and misunderstanding operator precedence
  • Incorrectly combining logical operators without parentheses
  • Using assignment = instead of comparison ==

Best Practices

  • Prefer === for comparisons to avoid type coercion
  • Use parentheses to clarify complex expressions
  • Comment logical conditions for readability
  • Keep arithmetic and assignments simple and readable

JS If Conditions

If statements allow your code to make decisions based on conditions. They are the foundation of conditional logic in JavaScript.

Key Concepts

  • Basic if statements
  • if...else for two-way branching
  • else if for multiple conditions
  • Nested conditions
  • Conditional (ternary) operator

The if statement executes a block of code if a condition evaluates to true. If the condition is false, the else block (if provided) executes instead. Multiple conditions can be handled using else if.

Conditions can be any expression that evaluates to a Boolean (true or false). You can nest if statements to create more complex decision trees, but readability should be maintained.

The ternary operator (condition ? expr1 : expr2) is a shorthand way to write simple if-else statements.

Syntax / Code Snippets


// Basic if statement
if (condition) {
  // code to execute if true
} else {
  // code to execute if false
}

// Ternary operator
let result = condition ? "Yes" : "No";
    
Example

// Check age eligibility
let age = 18;

if(age >= 18) {
  console.log("You are eligible to vote.");
} else {
  console.log("You are not eligible to vote yet.");
}
    
Live Editor

Real-World Use Case / Mini-Project

Create a simple grading system:


let score = Number(prompt("Enter your score (0-100):"));
let grade;

if(score >= 90) {
  grade = "A";
} else if(score >= 75) {
  grade = "B";
} else if(score >= 50) {
  grade = "C";
} else {
  grade = "F";
}

console.log("Your grade is:", grade);
    

Common Mistakes and Pitfalls

  • Using = instead of == or ===
  • Neglecting braces for multi-line blocks
  • Overcomplicating nested if statements
  • Incorrect comparison operators

Best Practices

  • Use === for comparisons
  • Keep nested conditions minimal for readability
  • Use ternary operators for simple decisions
  • Comment complex conditions for clarity

JS Loops

Loops allow you to execute a block of code multiple times without rewriting it. They are essential for automating repetitive tasks and iterating over data structures.

Key Concepts

  • for loop – iterate a known number of times
  • while loop – iterate while a condition is true
  • do...while loop – executes at least once
  • for...in – iterate over object properties
  • for...of – iterate over iterable objects like arrays
  • Using break and continue to control flow

The for loop is used when the number of iterations is known. It consists of initialization, condition, and increment/decrement steps. The while loop runs as long as a condition is true, and do...while guarantees at least one execution.

For objects, for...in iterates over keys, while for...of iterates over values in arrays, strings, or other iterable objects. break exits the loop immediately, and continue skips to the next iteration.

Using loops efficiently prevents code repetition and makes programs scalable and maintainable.

Syntax / Code Snippets


// For loop
for(let i = 0; i < 5; i++) {
  console.log(i);
}

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

// Do-while loop
let k = 0;
do {
  console.log(k);
  k++;
} while(k < 5);

// For...of
let arr = [10, 20, 30];
for(let val of arr) {
  console.log(val);
}

// For...in
let obj = {a:1, b:2};
for(let key in obj) {
  console.log(key, obj[key]);
}
    
Example

// Print numbers 1 to 5 using a for loop
for(let i = 1; i <= 5; i++) {
  console.log("Number:", i);
}

// Skip number 3 using continue
for(let i = 1; i <= 5; i++) {
  if(i === 3) continue;
  console.log("Number after skip:", i);
}
    
Live Editor

Real-World Use Case / Mini-Project

Generate a multiplication table for a user-entered number:


let num = Number(prompt("Enter a number for multiplication table:"));
for(let i = 1; i <= 10; i++) {
  console.log(`${num} x ${i} = ${num * i}`);
}
    

Common Mistakes and Pitfalls

  • Infinite loops due to incorrect condition or missing increment
  • Confusing for...in and for...of
  • Improper placement of break and continue
  • Off-by-one errors in loop counters

Best Practices

  • Use for...of for arrays and iterables
  • Keep loops simple and readable
  • Comment complex loop logic
  • Avoid unnecessary nested loops for performance

JS Strings

Strings in JavaScript are sequences of characters used to represent text. They are one of the most commonly used data types and come with a variety of methods for manipulation, formatting, and extraction.

Key Concepts

  • Creating strings using single, double, or backticks
  • String concatenation with + and template literals
  • String properties: length
  • String methods: toUpperCase, toLowerCase, slice, split, replace
  • Escaping characters and special characters

You can create strings using single quotes (' '), double quotes (" "), or backticks (` `). Backticks allow template literals which support embedded expressions using ${expression}. Template literals are very useful for dynamic content.

Strings have properties and methods. For example, length returns the number of characters, while toUpperCase() converts the string to uppercase. Methods like slice() extract substrings, split() divides a string into an array, and replace() substitutes text.

Escaping special characters with \\ allows you to include quotes or special symbols inside strings.

Syntax / Code Snippets


// String creation
let str1 = 'Hello';
let str2 = "World";
let str3 = `Template literal`;

// String methods
console.log(str1.length);
console.log(str2.toUpperCase());
console.log(`Combined: ${str1} ${str2}`);
    
Example

// Working with strings
let firstName = "John";
let lastName = "Doe";

console.log(firstName + " " + lastName);         // concatenation
console.log(`${firstName} ${lastName}`);         // template literal
console.log(firstName.toUpperCase());           // uppercase
console.log(lastName.toLowerCase());           // lowercase
console.log(firstName.length);                  // length
    
Live Editor

Real-World Use Case / Mini-Project

Create a small program that formats a user's full name properly:


let firstName = prompt("Enter your first name:");
let lastName = prompt("Enter your last name:");

let fullName = `${firstName.charAt(0).toUpperCase() + firstName.slice(1).toLowerCase()} ${lastName.charAt(0).toUpperCase() + lastName.slice(1).toLowerCase()}`;
console.log("Formatted Name:", fullName);
    

Common Mistakes and Pitfalls

  • Using incorrect quote types or forgetting to close them
  • Not using template literals for dynamic strings
  • Mixing numbers and strings without explicit conversion
  • Ignoring string immutability (methods return new strings)

Best Practices

  • Prefer template literals for readability
  • Use string methods instead of manual loops for manipulation
  • Always trim input strings if accepting user data
  • Comment string transformations for clarity

JS Numbers

Numbers in JavaScript represent numeric values, including integers and floating-point numbers. JavaScript provides a variety of operations and methods to work with numbers efficiently.

Key Concepts

  • Number types: integers and floats
  • Mathematical operations: +, -, *, /, %, **
  • Special numbers: Infinity, -Infinity, NaN
  • Number methods: toFixed(), parseInt(), parseFloat(), Math functions
  • Type conversion and numeric precision

Numbers in JavaScript are stored as 64-bit floating-point values. Arithmetic operations are straightforward, but floating-point precision errors can occur. Special values like NaN (Not a Number) and Infinity indicate exceptional conditions.

The Math object provides powerful functions like Math.round(), Math.floor(), Math.ceil(), Math.random(), and Math.sqrt() for calculations. Converting strings to numbers can be done using parseInt() and parseFloat().

Syntax / Code Snippets


// Basic numbers
let x = 10;        // integer
let y = 3.14;      // float

// Math operations
console.log(x + y);
console.log(x ** 2); // exponentiation
console.log(x % 3);  // modulus

// Number methods
console.log(y.toFixed(1)); // "3.1"
console.log(parseInt("42")); // 42
console.log(parseFloat("3.14")); // 3.14
    
Example

// Working with numbers
let price = 49.99;
let quantity = 3;
let total = price * quantity;

console.log("Total:", total.toFixed(2)); // formatted with 2 decimals

let randomNum = Math.floor(Math.random() * 100); // random number 0-99
console.log("Random number:", randomNum);
    
Live Editor

Real-World Use Case / Mini-Project

Calculate the total bill including tax:


let subtotal = Number(prompt("Enter subtotal:"));
let taxRate = 0.08; // 8%
let totalBill = subtotal + (subtotal * taxRate);
console.log("Total Bill (including tax):", totalBill.toFixed(2));
    

Common Mistakes and Pitfalls

  • Ignoring floating-point precision issues
  • Mixing strings and numbers without conversion
  • Incorrectly using parseInt for decimals
  • Misunderstanding NaN and Infinity

Best Practices

  • Use toFixed() for formatting numbers
  • Always convert user input to number before calculations
  • Use Math functions for precise calculations
  • Handle exceptional values (NaN, Infinity) carefully

JS Functions

Functions in JavaScript are reusable blocks of code that perform a specific task. They help organize code, reduce repetition, and improve maintainability.

Key Concepts

  • Function declaration vs function expression
  • Arrow functions (ES6)
  • Parameters and arguments
  • Return values
  • Scope and closures
  • Callback functions

A function can be declared using the function keyword, or assigned to a variable as a function expression. Arrow functions provide a concise syntax and lexical this binding.

Functions can accept parameters, which are placeholders for input values. They can also return values using the return statement. If no return is provided, the function returns undefined.

Functions can access variables in their outer scope (closure), enabling powerful programming patterns. Callbacks are functions passed as arguments to other functions, often used for asynchronous operations.

Syntax / Code Snippets


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

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

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

// Using functions
function add(a, b) {
  return a + b;
}

let sum = add(5, 3);
console.log("Sum:", sum);

const multiply = (x, y) => x * y;
console.log("Product:", multiply(4, 6));
    
Live Editor

Real-World Use Case / Mini-Project

Create a function that calculates the Body Mass Index (BMI) for a user:


function calculateBMI(weight, height) {
  return weight / (height * height);
}

let weight = Number(prompt("Enter your weight in kg:"));
let height = Number(prompt("Enter your height in meters:"));
let bmi = calculateBMI(weight, height);

console.log("Your BMI is:", bmi.toFixed(2));
    

Common Mistakes and Pitfalls

  • Forgetting to return a value
  • Confusing function parameters and arguments
  • Using arrow functions when this context is needed
  • Calling a function before it is defined (for expressions)

Best Practices

  • Use descriptive function names
  • Keep functions focused on a single task
  • Prefer arrow functions for short, concise callbacks
  • Comment complex logic inside functions

JS Objects

Objects in JavaScript are collections of key-value pairs, used to store structured data. They are fundamental for representing real-world entities and organizing related data and functionality.

Key Concepts

  • Creating objects using literals and constructors
  • Accessing properties: dot notation vs bracket notation
  • Adding, updating, and deleting properties
  • Nested objects and arrays
  • Object methods and the this keyword
  • Iterating over object properties using for...in

Objects are created using curly braces {} with key-value pairs. Each property has a name (key) and a value. Values can be of any type, including other objects or functions.

Properties are accessed using dot notation (obj.key) or bracket notation (obj["key"]). Methods are functions stored inside objects, and the this keyword refers to the object itself.

Objects can be nested, allowing complex data structures. Iterating through properties is often done with for...in loops, and modern ES6 provides Object.keys(), Object.values(), and Object.entries() for iteration.

Syntax / Code Snippets


// Object literal
let person = {
  name: "Alice",
  age: 25,
  greet: function() { console.log("Hello!"); }
};

// Accessing properties
console.log(person.name); // dot notation
console.log(person["age"]); // bracket notation

// Adding property
person.country = "USA";

// Deleting property
delete person.age;
    
Example

// Create an object
let car = {
  brand: "Toyota",
  model: "Corolla",
  year: 2020,
  honk: function() { console.log("Beep beep!"); }
};

// Access properties
console.log(car.brand);  // Toyota
console.log(car["model"]); // Corolla

// Call method
car.honk();

// Add new property
car.color = "Red";
console.log(car.color);
    
Live Editor

Real-World Use Case / Mini-Project

Create a simple product object with name, price, and a method to apply discount:


let product = {
  name: "Laptop",
  price: 1200,
  applyDiscount: function(percent) {
    this.price = this.price - (this.price * percent / 100);
  }
};

console.log("Original Price:", product.price);
product.applyDiscount(10);
console.log("Discounted Price:", product.price);
    

Common Mistakes and Pitfalls

  • Confusing dot and bracket notation
  • Misusing this in arrow functions inside objects
  • Trying to iterate non-enumerable properties
  • Over-nesting objects, reducing readability

Best Practices

  • Use descriptive property names
  • Keep objects focused on a single entity
  • Use methods for object behavior
  • Prefer Object.keys / Object.entries for iteration

JS Scope

Scope in JavaScript determines the accessibility of variables and functions in different parts of your code. Understanding scope is essential for avoiding bugs and managing variable lifetimes effectively.

Key Concepts

  • Global scope: variables accessible anywhere
  • Local / function scope: variables accessible only inside a function
  • Block scope: variables declared with let or const inside blocks
  • Lexical scope: functions remember the scope where they were defined
  • Scope chain: how JS looks up variables
  • Variable hoisting and its effect on scope

Variables declared with var have function scope, meaning they are accessible anywhere inside the function they are declared. Variables declared with let or const have block scope, limited to the block, statement, or expression where they are used.

Global variables are accessible anywhere in your code, but overusing them can lead to conflicts. Lexical scope allows functions to access variables from the environment in which they were created. The scope chain determines how JavaScript resolves variable references, moving up from local to global scope.

Hoisting moves variable and function declarations to the top of their scope. However, only var variables are hoisted with an initial undefined value, while let and const remain in a temporal dead zone until initialized.

Syntax / Code Snippets


// Global scope
let globalVar = "I'm global";

function myFunction() {
  // Local scope
  let localVar = "I'm local";
  console.log(globalVar); // accessible
  console.log(localVar);  // accessible
}

myFunction();
console.log(globalVar); // accessible
// console.log(localVar); // Error: localVar is not defined

// Block scope
if(true) {
  let blockVar = "Inside block";
  const constVar = "Also inside block";
}
// console.log(blockVar); // Error
// console.log(constVar); // Error
    
Example

// Function and block scope
function testScope() {
  var functionVar = "Function scope";
  let blockVar = "Block scope";

  if(true) {
    let innerBlock = "Inner block scope";
    console.log(innerBlock); // accessible here
  }
  // console.log(innerBlock); // Error: not accessible
  console.log(functionVar); // accessible
}

testScope();
    
Live Editor

Real-World Use Case / Mini-Project

Create a counter function that keeps track of its count internally (closure example):


function createCounter() {
  let count = 0; // local to function, preserved via closure
  return function() {
    count++;
    return count;
  };
}

let counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
    

Common Mistakes and Pitfalls

  • Using global variables unnecessarily
  • Expecting var to behave like let or const
  • Misunderstanding closures and variable lifetimes
  • Accessing block-scoped variables outside their block

Best Practices

  • Use let and const instead of var
  • Minimize global variables
  • Use closures intentionally to encapsulate state
  • Comment variable scopes in complex functions

JS Dates

Dates in JavaScript allow you to work with time and date values. The built-in Date object provides methods to create, manipulate, and format dates and times.

Key Concepts

  • Creating dates with new Date()
  • Getting date components: getFullYear, getMonth, getDate, getDay, getHours, etc.
  • Setting date components: setFullYear, setMonth, etc.
  • Formatting dates as strings
  • Time in milliseconds since Unix epoch
  • Using Date for comparisons and calculations

You can create a Date object in multiple ways, including no-argument constructor (current date/time), passing a date string, or passing year, month, day, etc. Months are zero-indexed (January = 0).

The Date object provides getter methods to retrieve parts of the date, and setter methods to modify them. You can perform calculations like differences in time by subtracting Date objects, which returns milliseconds.

Formatting is often done using toDateString(), toISOString(), or custom formatting by extracting components manually.

Syntax / Code Snippets


// Create dates
let now = new Date();
let specificDate = new Date(2026, 2, 2); // Year, Month (0-indexed), Day

// Get components
console.log(now.getFullYear());
console.log(now.getMonth());
console.log(now.getDate());
console.log(now.getDay());

// Set components
now.setFullYear(2027);
now.setMonth(11); // December
console.log(now);

// Formatting
console.log(now.toDateString());
console.log(now.toISOString());
    
Example

// Current date and time
let today = new Date();
console.log("Today:", today.toDateString());
console.log("Time:", today.toTimeString());

// Specific date
let birthday = new Date(1995, 6, 15); // July 15, 1995
console.log("Birthday:", birthday.toDateString());

// Date arithmetic
let diff = today - birthday;
let days = Math.floor(diff / (1000 * 60 * 60 * 24));
console.log("Days since birthday:", days);
    
Live Editor

Real-World Use Case / Mini-Project

Create a countdown timer to a future date:


let eventDate = new Date(2026, 11, 31); // Dec 31, 2026
let now = new Date();

let diffMs = eventDate - now;
let daysLeft = Math.floor(diffMs / (1000 * 60 * 60 * 24));

console.log(`Days left until event: ${daysLeft}`);
    

Common Mistakes and Pitfalls

  • Zero-indexed months (January = 0)
  • Mixing string parsing with Date arithmetic incorrectly
  • Forgetting that Date subtraction returns milliseconds
  • Ignoring timezones when comparing dates

Best Practices

  • Use toISOString() or libraries for consistent formatting
  • Always check month index when creating dates manually
  • Convert milliseconds to days/hours/minutes for clarity
  • Comment complex date calculations

JS Temporal (New)

The Temporal API is a modern JavaScript standard (ES2023/ES2024) for working with dates, times, and time zones more reliably than the legacy Date object. It provides immutable, precise, and easy-to-use objects for complex time computations.

Key Concepts

  • Temporal.PlainDate – represents calendar dates
  • Temporal.PlainTime – represents time of day
  • Temporal.ZonedDateTime – date and time in a specific time zone
  • Temporal.Duration – represents differences between dates/times
  • Immutable objects – operations return new instances
  • Better timezone handling compared to legacy Date

The Temporal API solves many issues with Date, like ambiguous months, daylight savings, and time zone inconsistencies. Temporal objects are immutable, meaning methods like add() or with() return a new object without modifying the original.

You can create dates, times, or zoned date-times using constructors like Temporal.PlainDate.from() or Temporal.ZonedDateTime.from(). Temporal also provides rich methods for arithmetic, comparison, and formatting, making date-time code much safer and predictable.

Syntax / Code Snippets


// PlainDate
let date = Temporal.PlainDate.from('2026-03-02');
console.log(date.toString()); // 2026-03-02

// PlainTime
let time = Temporal.PlainTime.from('14:30:00');
console.log(time.toString()); // 14:30:00

// ZonedDateTime
let zdt = Temporal.ZonedDateTime.from('2026-03-02T14:30[Asia/Kolkata]');
console.log(zdt.toString());

// Duration
let duration = Temporal.Duration.from({ hours: 2, minutes: 30 });
console.log(duration.toString()); // PT2H30M
    
Example

// Calculate a date 10 days from today using Temporal
let today = Temporal.PlainDate.from('2026-03-02');
let future = today.add({ days: 10 });
console.log("10 days from today:", future.toString());

// Working with time zones
let meeting = Temporal.ZonedDateTime.from('2026-03-02T09:00[Asia/Kolkata]');
console.log("Meeting time in Kolkata:", meeting.toString());
    
Live Editor

Real-World Use Case / Mini-Project

Schedule an event and display it in multiple time zones:


let event = Temporal.ZonedDateTime.from('2026-03-15T10:00[Asia/Kolkata]');
console.log("Event in Kolkata:", event.toString());

let eventNY = event.withTimeZone('America/New_York');
console.log("Event in New York:", eventNY.toString());
    

Common Mistakes and Pitfalls

  • Assuming Temporal modifies objects (it's immutable)
  • Confusing legacy Date API with Temporal methods
  • Incorrect time zone string formats
  • Using arithmetic on Temporal objects like regular numbers

Best Practices

  • Prefer Temporal over legacy Date for modern apps
  • Always handle time zones explicitly
  • Use immutable operations to avoid side effects
  • Format dates using Temporal’s built-in methods

JS Arrays

Arrays in JavaScript are ordered collections of values. They can store any type of data, including numbers, strings, objects, and even other arrays. Arrays are essential for managing lists and sequences efficiently.

Key Concepts

  • Creating arrays using literals and constructors
  • Accessing elements by index
  • Array properties: length
  • Common methods: push, pop, shift, unshift, slice, splice, map, filter, reduce
  • Iterating arrays with for, for...of, and forEach
  • Multidimensional arrays

Arrays are created using square brackets [] with comma-separated values, or with the Array() constructor. Each element has an index starting from 0.

Arrays are dynamic; you can add or remove elements at runtime. Methods like push() and pop() work on the end of the array, while shift() and unshift() work on the start. Higher-order methods like map(), filter(), and reduce() enable functional programming patterns.

Arrays can be nested to create multidimensional structures, making them suitable for matrices or tabular data.

Syntax / Code Snippets


// Array creation
let fruits = ["Apple", "Banana", "Cherry"];
let numbers = new Array(1, 2, 3);

// Access elements
console.log(fruits[0]); // Apple

// Array methods
fruits.push("Orange");
fruits.pop();
let citrus = fruits.slice(1,3);

// Iteration
fruits.forEach(fruit => console.log(fruit));
    
Example

// Working with arrays
let colors = ["Red", "Green", "Blue"];
colors.push("Yellow"); // add to end
console.log(colors);

let removed = colors.pop(); // remove last
console.log("Removed:", removed);
console.log(colors);

let upperColors = colors.map(c => c.toUpperCase());
console.log("Uppercase:", upperColors);
    
Live Editor

Real-World Use Case / Mini-Project

Create a simple shopping cart:


let cart = [];

function addToCart(item) {
  cart.push(item);
}

addToCart("Laptop");
addToCart("Mouse");
addToCart("Keyboard");

console.log("Shopping Cart:", cart);

let expensiveItems = cart.filter(item => item.includes("Laptop"));
console.log("Expensive Items:", expensiveItems);
    

Common Mistakes and Pitfalls

  • Accessing out-of-range indexes
  • Modifying arrays while iterating without caution
  • Using for...in instead of for...of for arrays
  • Confusing slice() (non-destructive) and splice() (destructive)

Best Practices

  • Use const for arrays that should not be reassigned
  • Prefer higher-order methods (map, filter, reduce) for cleaner code
  • Keep arrays homogeneous where possible for simplicity
  • Comment complex transformations or nested arrays

JS HTML

JavaScript can interact with HTML to dynamically change content, attributes, and structure of web pages. This enables interactive and responsive web experiences.

Key Concepts

  • Accessing HTML elements via document
  • Manipulating inner content: innerHTML, textContent
  • Changing attributes: getAttribute, setAttribute
  • Creating, appending, and removing elements dynamically
  • Integrating JS with HTML events

JavaScript interacts with HTML using the Document Object Model (DOM), which represents HTML elements as objects. You can access elements by id, class, tag, or CSS selectors. Modifying innerHTML or textContent changes what users see on the page.

You can also manipulate attributes, like changing an image src or link href. Dynamic creation and deletion of elements allow complex interfaces without reloading the page. Combining these operations with events makes web pages interactive.

Syntax / Code Snippets


// Accessing elements
let heading = document.getElementById("title");
let paragraphs = document.getElementsByClassName("text");
let links = document.querySelectorAll("a");

// Changing content
heading.textContent = "New Heading";
paragraphs[0].innerHTML = "Updated paragraph";

// Changing attributes
let image = document.querySelector("img");
image.setAttribute("src", "new-image.png");
    
Example

// Change heading text dynamically
document.getElementById("title").textContent = "Welcome to LearnX!";

// Change image source
document.querySelector("img").setAttribute("src", "https://via.placeholder.com/150");

// Add a new paragraph
let newPara = document.createElement("p");
newPara.textContent = "This paragraph was added dynamically!";
document.body.appendChild(newPara);
    
Live Editor

Real-World Use Case / Mini-Project

Create a dynamic user greeting:


let username = prompt("Enter your name:");
let greeting = document.createElement("h2");
greeting.textContent = `Hello, ${username}! Welcome to LearnX.`;
document.body.appendChild(greeting);
    

Common Mistakes and Pitfalls

  • Trying to access elements before the DOM loads
  • Mixing innerHTML and textContent incorrectly
  • Not checking if getElementById or querySelector returns null
  • Forgetting to append newly created elements

Best Practices

  • Use textContent for plain text to prevent XSS
  • Check for element existence before modifying
  • Keep DOM manipulation minimal for performance
  • Use createElement and append for dynamic content

JS HTML DOM

The Document Object Model (DOM) represents the HTML structure of a web page as a tree of objects. JavaScript can traverse, modify, and interact with this tree to create dynamic web pages.

Key Concepts

  • DOM tree structure: elements, nodes, attributes, text
  • Accessing elements: getElementById, getElementsByClassName, querySelector
  • Modifying elements: innerHTML, textContent, style
  • Traversing the DOM: parentNode, childNodes, nextSibling, previousSibling
  • Creating and removing elements dynamically

The DOM treats every HTML element as an object with properties and methods. You can access elements using multiple selectors, change their content or style, and dynamically add or remove elements.

Traversing the DOM allows you to move between parent, child, and sibling nodes. Modern methods like querySelector and querySelectorAll provide flexibility similar to CSS selectors. Dynamically manipulating the DOM is key for interactive UIs, live updates, and single-page applications.

Syntax / Code Snippets


// Accessing elements
let title = document.getElementById("title");
let items = document.getElementsByClassName("item");
let firstItem = document.querySelector(".item");

// Changing content and style
title.textContent = "Updated Title";
firstItem.style.color = "blue";

// Creating elements
let newDiv = document.createElement("div");
newDiv.textContent = "New dynamically added div";
document.body.appendChild(newDiv);

// Traversing
let parent = firstItem.parentNode;
let next = firstItem.nextElementSibling;
    
Example

// DOM traversal and manipulation
let container = document.getElementById("container");
let firstChild = container.firstElementChild;
console.log("First child:", firstChild.textContent);

let lastChild = container.lastElementChild;
lastChild.style.backgroundColor = "yellow";

// Add new element
let newPara = document.createElement("p");
newPara.textContent = "Hello from JS DOM!";
container.appendChild(newPara);
    
Live Editor

Real-World Use Case / Mini-Project

Create a dynamic to-do list where users can add and remove items:


let input = document.getElementById("todo-input");
let list = document.getElementById("todo-list");

function addTodo() {
  let value = input.value.trim();
  if(value) {
    let li = document.createElement("li");
    li.textContent = value;
    li.onclick = () => li.remove(); // remove on click
    list.appendChild(li);
    input.value = "";
  }
}
    

Common Mistakes and Pitfalls

  • Accessing elements before DOM loads
  • Confusing childNodes and children (text nodes included)
  • Forgetting to append created elements
  • Mixing innerHTML and textContent carelessly

Best Practices

  • Use querySelector for flexible selectors
  • Minimize DOM manipulation for performance
  • Use textContent for text to avoid XSS
  • Keep traversal logic clear and commented

JS Events

Events in JavaScript allow you to respond to user interactions such as clicks, typing, mouse movements, form submissions, and more. Event-driven programming is central to interactive web applications.

Key Concepts

  • Event types: click, input, submit, mouseover, keydown, etc.
  • Attaching event listeners: addEventListener
  • Event handler functions and the event object
  • Event propagation: bubbling and capturing
  • Removing event listeners
  • Using inline HTML event attributes (not recommended)

Events allow your code to react to user actions in real-time. You can attach handlers using addEventListener, which accepts the event type, a callback function, and an optional options object.

The event object provides information about the event, such as the target element, key pressed, mouse coordinates, etc. Understanding event propagation (bubbling and capturing) is important when multiple elements handle the same event.

Although HTML inline attributes like onclick exist, using addEventListener is preferred for cleaner, maintainable, and scalable code.

Syntax / Code Snippets


// Attaching event listener
let button = document.getElementById("btn");
button.addEventListener("click", function(event) {
  console.log("Button clicked!", event.target);
});

// Event object
document.addEventListener("keydown", function(e) {
  console.log(`Key pressed: ${e.key}`);
});

// Removing event listener
function greet() { console.log("Hello!"); }
button.addEventListener("click", greet);
button.removeEventListener("click", greet);
    
Example

// Button click event
let button = document.getElementById("myBtn");
button.addEventListener("click", function(event) {
  alert("You clicked the button!");
  console.log("Event target:", event.target);
});

// Mouseover event
let box = document.getElementById("hoverBox");
box.addEventListener("mouseover", () => {
  box.style.backgroundColor = "lightblue";
});
box.addEventListener("mouseout", () => {
  box.style.backgroundColor = "";
});
    
Live Editor

Real-World Use Case / Mini-Project

Create a dynamic counter that increments when a button is clicked:


let count = 0;
let counterDisplay = document.getElementById("counter");
let incrementBtn = document.getElementById("increment");

incrementBtn.addEventListener("click", () => {
  count++;
  counterDisplay.textContent = `Count: ${count}`;
});
    

Common Mistakes and Pitfalls

  • Not attaching events after DOM elements exist
  • Using inline events instead of addEventListener
  • Not using the event object when needed
  • Forgetting to remove unnecessary listeners causing memory leaks

Best Practices

  • Always use addEventListener instead of inline events
  • Use arrow functions for concise handlers when this is not needed
  • Remove listeners when no longer needed to optimize performance
  • Leverage event delegation for many child elements

JS Projects (New)

This section demonstrates practical JavaScript projects combining HTML and DOM manipulation. These mini-projects help solidify concepts learned and provide real-world examples of interactive web applications.

Key Concepts

  • Combining JS with HTML and DOM for interactive UI
  • Event-driven programming for dynamic content
  • Using arrays and objects to store application data
  • Form handling and validation
  • Basic animations and effects
  • Debugging and structuring project code

Projects allow you to apply multiple concepts at once. For example, creating a to-do list combines arrays, DOM manipulation, events, and conditionals. Projects can be enhanced incrementally, e.g., adding storage with localStorage, styling changes, or validation logic.

Mini-projects encourage experimentation and problem-solving. Each project should be modular, maintainable, and demonstrate core JavaScript functionality.

Mini-Project Example: To-Do List

// HTML structure assumed:
// 
// 
// 
    let input = document.getElementById("taskInput"); let addBtn = document.getElementById("addTask"); let list = document.getElementById("taskList"); addBtn.addEventListener("click", () => { let task = input.value.trim(); if(task) { let li = document.createElement("li"); li.textContent = task; li.onclick = () => li.remove(); // remove task on click list.appendChild(li); input.value = ""; } });
    Live Editor

    Real-World Mini-Projects

    • Shopping Cart: Add/remove items dynamically and calculate total price.
    • Countdown Timer: Display days, hours, minutes, and seconds until an event.
    • Interactive Quiz: Present questions, track answers, and display score.
    • Image Gallery: Dynamically generate images and allow filtering or sorting.

    Common Mistakes and Pitfalls

    • Not validating input before adding elements
    • Mixing data storage and DOM code, making it messy
    • Forgetting to clear input fields after submission
    • Not handling edge cases (empty list, duplicates, etc.)

    Best Practices

    • Keep project code modular and organized
    • Separate logic from UI updates where possible
    • Comment major sections of project code
    • Use event delegation for dynamic elements to optimize performance
    • Test edge cases and user interactions thoroughly

    JS Functions

    Functions are reusable blocks of code that perform a specific task. They allow you to structure your code, reduce repetition, and create modular applications.

    Key Concepts

    • Function declaration vs function expression
    • Arrow functions (ES6+)
    • Parameters and arguments
    • Return values
    • Default parameters
    • Rest parameters and spread operator
    • Higher-order functions
    • Closures

    Functions can be declared using the function keyword or assigned as expressions to variables. ES6 introduced arrow functions for concise syntax, especially in callbacks.

    Functions can take parameters and return values. Default parameters provide fallback values if arguments are not supplied. Rest parameters allow functions to accept a variable number of arguments, while the spread operator can expand arrays into individual elements.

    Higher-order functions accept other functions as arguments or return functions. Closures allow inner functions to access outer function variables, enabling private state and encapsulation.

    Syntax / Code Snippets

    
    // Function declaration
    function greet(name = "User") {
      return `Hello, ${name}!`;
    }
    
    // Function expression
    const add = function(a, b) {
      return a + b;
    };
    
    // Arrow function
    const square = x => x * x;
    
    // Rest parameters
    function sum(...numbers) {
      return numbers.reduce((acc, val) => acc + val, 0);
    }
    
    // Higher-order function
    function multiplier(factor) {
      return function(x) {
        return x * factor;
      };
    }
        
    Example
    
    // Greet function
    function greet(name = "LearnX") {
      console.log(`Hello, ${name}!`);
    }
    greet();
    greet("AK");
    
    // Sum using rest parameters
    function sum(...nums) {
      return nums.reduce((a,b) => a+b, 0);
    }
    console.log("Sum:", sum(1,2,3,4,5));
    
    // Closure example
    function counter() {
      let count = 0;
      return function() {
        count++;
        return count;
      };
    }
    let increment = counter();
    console.log(increment()); // 1
    console.log(increment()); // 2
        
    Live Editor

    Real-World Use Case / Mini-Project

    Create a reusable calculator function:

    
    function calculator(operation) {
      return function(a, b) {
        if(operation === "add") return a+b;
        if(operation === "subtract") return a-b;
        if(operation === "multiply") return a*b;
        if(operation === "divide") return a/b;
      };
    }
    
    const addFunc = calculator("add");
    console.log(addFunc(10,5)); // 15
        

    Common Mistakes and Pitfalls

    • Not returning values from functions
    • Confusing function declaration and expression hoisting
    • Improperly using closures without understanding scope
    • Overusing global variables inside functions

    Best Practices

    • Keep functions small and single-purpose
    • Use default parameters for optional arguments
    • Prefer arrow functions for concise callbacks
    • Use closures intentionally for private state
    • Document parameters and return values

    JS Objects

    Objects in JavaScript are collections of key-value pairs. They allow you to store, organize, and manipulate complex data in a structured way, making them essential for any web application.

    Key Concepts

    • Object literals and constructors
    • Properties and methods
    • Accessing values: dot notation and bracket notation
    • Nested objects and arrays
    • Object destructuring (ES6+)
    • Object methods: Object.keys, Object.values, Object.entries
    • Prototypes and inheritance basics

    Objects are created using curly braces {} or constructors. Each property has a key (string or symbol) and a value (any type). Methods are functions assigned to object properties. Nested objects allow representing hierarchical data.

    Accessing properties can be done with dot notation (e.g., obj.key) or bracket notation (e.g., obj["key"]). ES6 introduced object destructuring, allowing concise extraction of multiple properties. Built-in methods like Object.keys and Object.entries help iterate over object data efficiently.

    Syntax / Code Snippets

    
    // Object literal
    let person = {
      name: "AK",
      age: 25,
      greet: function() {
        return `Hello, my name is ${this.name}`;
      }
    };
    
    // Access properties
    console.log(person.name);
    console.log(person["age"]);
    
    // Nested objects
    let student = {
      name: "Sara",
      scores: { math: 90, english: 85 }
    };
    
    // Object methods
    console.log(Object.keys(person));
    console.log(Object.entries(student));
    
    // Destructuring
    let { name, age } = person;
    console.log(name, age);
        
    Example
    
    // Create an object
    let car = {
      brand: "Toyota",
      model: "Corolla",
      year: 2026,
      details: function() {
        return `${this.brand} ${this.model} (${this.year})`;
      }
    };
    
    // Access and update properties
    console.log(car.brand);
    car.year = 2027;
    console.log(car.details());
    
    // Nested object
    car.owner = { name: "AK", license: "XYZ123" };
    console.log(car.owner.name);
    
    // Object destructuring
    let { brand, model } = car;
    console.log(brand, model);
        
    Live Editor

    Real-World Use Case / Mini-Project

    Create a simple contact book:

    
    let contacts = [
      { name: "Alice", phone: "12345" },
      { name: "Bob", phone: "67890" }
    ];
    
    // Add a contact
    contacts.push({ name: "Charlie", phone: "54321" });
    
    // Print contact names
    contacts.forEach(c => console.log(c.name));
        

    Common Mistakes and Pitfalls

    • Confusing dot vs bracket notation
    • Overwriting objects unintentionally
    • Not using this correctly inside methods
    • Deeply nested objects without clear structure

    Best Practices

    • Use descriptive keys
    • Keep objects shallow when possible for readability
    • Use methods inside objects for reusable behavior
    • Leverage destructuring for clean code
    • Use arrays for collections of objects instead of multiple separate variables

    JS Classes

    Classes in JavaScript provide a blueprint for creating objects with shared properties and methods. They enable object-oriented programming, making code organized, reusable, and modular.

    Key Concepts

    • Class declaration and instantiation
    • Constructor method
    • Instance methods and properties
    • Static methods
    • Inheritance using extends and super
    • Encapsulation using getters and setters
    • Private fields (ES2022+)

    Classes are syntactic sugar over JavaScript’s prototype-based inheritance. The constructor initializes new objects, while instance methods define behavior. Static methods belong to the class itself rather than an instance.

    Inheritance allows one class to extend another, sharing properties and methods using extends and super(). Getters and setters provide controlled access to properties. Private fields, prefixed with #, encapsulate data for true privacy.

    Syntax / Code Snippets

    
    // Class declaration
    class Person {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
    
      greet() {
        return `Hello, my name is ${this.name}`;
      }
    
      // Getter
      get info() {
        return `${this.name}, ${this.age} years old`;
      }
    
      // Setter
      set updateName(newName) {
        this.name = newName;
      }
    
      // Static method
      static species() {
        return "Homo Sapiens";
      }
    }
    
    // Inheritance
    class Student extends Person {
      constructor(name, age, grade) {
        super(name, age);
        this.grade = grade;
      }
    
      studentInfo() {
        return `${this.name} is in grade ${this.grade}`;
      }
    }
        
    Example
    
    // Create instance
    let ak = new Person("AK", 25);
    console.log(ak.greet());
    console.log(ak.info);
    
    // Update name using setter
    ak.updateName = "AK Sharma";
    console.log(ak.info);
    
    // Use static method
    console.log(Person.species());
    
    // Inheritance example
    let student1 = new Student("Sara", 20, "A");
    console.log(student1.studentInfo());
    console.log(student1.greet());
        
    Live Editor

    Real-World Use Case / Mini-Project

    Create a simple bank account class with deposit and withdraw functionality:

    
    class BankAccount {
      constructor(owner, balance=0) {
        this.owner = owner;
        this.balance = balance;
      }
    
      deposit(amount) {
        this.balance += amount;
        return this.balance;
      }
    
      withdraw(amount) {
        if(amount > this.balance) return "Insufficient funds";
        this.balance -= amount;
        return this.balance;
      }
    }
    
    let account = new BankAccount("AK", 1000);
    console.log(account.deposit(500)); // 1500
    console.log(account.withdraw(2000)); // Insufficient funds
        

    Common Mistakes and Pitfalls

    • Forgetting to call super() in derived classes
    • Confusing instance vs static methods
    • Modifying class methods on prototype incorrectly
    • Overusing global variables instead of class properties

    Best Practices

    • Keep classes focused on a single responsibility
    • Use getters/setters to control property access
    • Favor private fields for sensitive data
    • Leverage inheritance for shared behavior, composition when possible
    • Document class methods and properties clearly

    JS Asynchronous

    Asynchronous JavaScript allows code to run without blocking the main thread. It’s essential for handling tasks like API calls, timers, file reading, and user interactions while keeping the UI responsive.

    Key Concepts

    • Callbacks
    • Promises
    • Async/Await (ES2017+)
    • setTimeout and setInterval
    • Error handling in async code
    • Event loop and microtasks
    • Chaining asynchronous operations

    In JavaScript, most operations are synchronous by default, which can block execution. Asynchronous techniques let you defer operations to complete later while other code continues to run. Callbacks are the traditional approach, but they can lead to “callback hell” when nested deeply.

    Promises provide a cleaner, chainable way to handle asynchronous operations. Async/Await allows writing asynchronous code in a synchronous style, making it easier to read and maintain. Understanding the event loop is important for reasoning about when asynchronous tasks execute relative to synchronous code.

    Syntax / Code Snippets

    
    // Callback example
    function fetchData(callback) {
      setTimeout(() => {
        callback("Data received!");
      }, 1000);
    }
    
    // Promise example
    let fetchPromise = new Promise((resolve, reject) => {
      setTimeout(() => resolve("Data received via Promise"), 1000);
    });
    
    // Async/Await example
    async function getData() {
      let data = await fetchPromise;
      console.log(data);
    }
        
    Example
    
    // Using a callback
    function greetCallback(name, callback) {
      setTimeout(() => {
        callback(`Hello, ${name}`);
      }, 1000);
    }
    
    greetCallback("AK", msg => console.log(msg));
    
    // Using a Promise
    let promise = new Promise((resolve, reject) => {
      setTimeout(() => resolve("Promise resolved!"), 1500);
    });
    
    promise.then(msg => console.log(msg));
    
    // Async/Await
    async function showData() {
      let result = await promise;
      console.log("Async/Await:", result);
    }
    showData();
        
    Live Editor

    Real-World Use Case / Mini-Project

    Fetch data from a public API using async/await:

    
    async function fetchUsers() {
      try {
        let response = await fetch("https://jsonplaceholder.typicode.com/users");
        let users = await response.json();
        console.log("Users:", users);
      } catch (error) {
        console.error("Error fetching users:", error);
      }
    }
    fetchUsers();
        

    Common Mistakes and Pitfalls

    • Forgetting to handle errors in promises or async functions
    • Nesting callbacks too deeply (“callback hell”)
    • Using await outside of async functions
    • Blocking the main thread with synchronous code

    Best Practices

    • Use promises or async/await over callbacks for cleaner code
    • Always handle errors with catch or try/catch
    • Use descriptive names for asynchronous functions
    • Keep asynchronous operations modular and reusable
    • Understand the event loop and microtask queue for timing issues

    JS Modules

    JavaScript modules allow you to split code into reusable files with private and public parts. Modules help organize large projects, promote encapsulation, and improve maintainability.

    Key Concepts

    • Exporting variables, functions, and classes
    • Importing modules
    • Named vs default exports
    • ES6 module syntax: import/export
    • Dynamic imports
    • Benefits: encapsulation, maintainability, and reuse

    Modules let you divide code into separate files and only expose the parts needed externally. Named exports allow multiple exports per file, while default exports allow a single export per module.

    Modules must be loaded via type="module" in script tags in HTML or using build tools like Webpack. Dynamic imports allow importing modules asynchronously when needed. Using modules improves code organization, reduces naming conflicts, and supports maintainable codebases.

    Syntax / Code Snippets

    
    // math.js
    export function add(a, b) {
      return a + b;
    }
    
    export const PI = 3.14159;
    
    // Default export
    export default class Calculator {
      multiply(a, b) {
        return a * b;
      }
    }
    
    // main.js
    import { add, PI } from './math.js';
    import Calculator from './math.js';
    
    console.log(add(2,3));
    console.log(PI);
    
    let calc = new Calculator();
    console.log(calc.multiply(4,5));
        
    Example
    
    // utils.js
    export function greet(name) {
      return `Hello, ${name}!`;
    }
    
    export const version = "1.0";
    
    // app.js
    import { greet, version } from './utils.js';
    
    console.log(greet("AK"));
    console.log("App Version:", version);
        
    Live Editor

    Real-World Use Case / Mini-Project

    Modularize a small utility library:

    
    // stringUtils.js
    export function capitalize(str) {
      return str.charAt(0).toUpperCase() + str.slice(1);
    }
    
    export function reverse(str) {
      return str.split('').reverse().join('');
    }
    
    // main.js
    import { capitalize, reverse } from './stringUtils.js';
    console.log(capitalize("learnx")); // Learnx
    console.log(reverse("javascript")); // tpircsavaj
        

    Common Mistakes and Pitfalls

    • Forgetting type="module" in HTML
    • Confusing named and default exports
    • Incorrect file paths in import statements
    • Trying to use modules in environments without support

    Best Practices

    • Keep each module focused on a single responsibility
    • Use descriptive names for exports
    • Prefer default exports when a module has one primary functionality
    • Use dynamic imports for lazy-loading when necessary
    • Document module APIs clearly for maintainability

    JS Meta & Proxy

    JavaScript provides meta-programming capabilities that allow you to intercept and customize behavior of objects. Proxies and Reflect APIs are powerful tools for controlling object operations dynamically.

    Key Concepts

    • Proxy objects for intercepting operations (get, set, delete, etc.)
    • Handlers: traps for different operations
    • Reflect API for default behavior
    • Use cases: validation, logging, access control
    • Meta-programming for dynamic object behavior

    Proxies wrap an object and intercept operations performed on it. A handler object defines traps such as get, set, has, and more. You can control, modify, or block these operations as needed.

    The Reflect API allows you to call the default behavior inside a trap. Together, Proxies and Reflect enable meta-programming, giving you tools to validate data, implement computed properties, or add logging and debugging dynamically.

    Syntax / Code Snippets

    
    // Proxy example
    let target = { name: "AK", age: 25 };
    let handler = {
      get: function(obj, prop) {
        console.log(`Accessed property: ${prop}`);
        return prop in obj ? obj[prop] : "Property not found";
      },
      set: function(obj, prop, value) {
        console.log(`Setting ${prop} to ${value}`);
        obj[prop] = value;
        return true;
      }
    };
    
    let proxy = new Proxy(target, handler);
    console.log(proxy.name);
    proxy.age = 26;
    
    // Reflect API
    Reflect.set(target, "name", "AK Sharma");
    console.log(Reflect.get(target, "name"));
        
    Example
    
    // Create a proxy for validation
    let user = { name: "AK", age: 25 };
    let validator = {
      set(obj, prop, value) {
        if(prop === "age" && typeof value !== "number") {
          throw new TypeError("Age must be a number");
        }
        obj[prop] = value;
        return true;
      }
    };
    
    let proxiedUser = new Proxy(user, validator);
    proxiedUser.age = 30; // works
    // proxiedUser.age = "thirty"; // throws error
    console.log(proxiedUser.age);
        
    Live Editor

    Real-World Use Case / Mini-Project

    Create a logging proxy to track all property accesses:

    
    let settings = { theme: "dark", notifications: true };
    let logger = new Proxy(settings, {
      get(target, prop) {
        console.log(`Property "${prop}" accessed:`, target[prop]);
        return target[prop];
      },
      set(target, prop, value) {
        console.log(`Property "${prop}" changed from ${target[prop]} to ${value}`);
        target[prop] = value;
        return true;
      }
    });
    
    logger.theme; // Access logs
    logger.notifications = false; // Change logs
        

    Common Mistakes and Pitfalls

    • Forgetting to return true in set traps
    • Not handling non-existing properties properly
    • Overusing proxies for simple objects (adds overhead)
    • Ignoring default behavior without using Reflect

    Best Practices

    • Use proxies for advanced use-cases like validation or logging
    • Always consider performance impact
    • Use Reflect methods inside traps to maintain default behavior
    • Keep handlers simple and readable
    • Document proxies clearly, as they change object behavior dynamically

    JS Typed Arrays

    Typed Arrays provide a way to handle raw binary data efficiently in JavaScript. They are used for performance-critical applications like WebGL, audio processing, and large numerical datasets.

    Key Concepts

    • ArrayBuffer: fixed-length binary data buffer
    • Typed array views: Int8Array, Uint8Array, Float32Array, etc.
    • DataView for flexible data access
    • Endianness and binary representation
    • Use cases: graphics, multimedia, scientific calculations
    • Efficient memory operations compared to normal arrays

    Typed Arrays allow storing and manipulating binary data with strict types. Unlike normal arrays, they have fixed sizes and uniform data types, making them faster for numerical computations.

    The ArrayBuffer represents raw memory, and typed array views like Int16Array or Float32Array provide a convenient way to read and write data in specific formats. DataView allows reading and writing multiple data types at arbitrary offsets.

    Syntax / Code Snippets

    
    // Create a buffer of 16 bytes
    let buffer = new ArrayBuffer(16);
    
    // Create a typed array view
    let int32View = new Int32Array(buffer);
    int32View[0] = 42;
    int32View[1] = 100;
    
    // Using DataView for custom offsets
    let view = new DataView(buffer);
    view.setInt8(8, 64);
    console.log(view.getInt8(8));
        
    Example
    
    // Create Float32Array for graphics
    let floatBuffer = new ArrayBuffer(16);
    let floatView = new Float32Array(floatBuffer);
    
    floatView[0] = 1.5;
    floatView[1] = 2.5;
    floatView[2] = 3.5;
    floatView[3] = 4.5;
    
    console.log("Float32Array:", floatView);
    
    // Access raw bytes with DataView
    let dataView = new DataView(floatBuffer);
    console.log("Byte at offset 0:", dataView.getUint8(0));
        
    Live Editor

    Real-World Use Case / Mini-Project

    Use Typed Arrays to manipulate pixel data for a small image effect:

    
    let width = 2, height = 2;
    let pixelBuffer = new ArrayBuffer(width * height * 4); // RGBA
    let pixels = new Uint8ClampedArray(pixelBuffer);
    
    // Set pixel colors (red, green, blue, alpha)
    pixels[0] = 255; // red
    pixels[1] = 0;   // green
    pixels[2] = 0;   // blue
    pixels[3] = 255; // alpha
    
    pixels[4] = 0; pixels[5] = 255; pixels[6] = 0; pixels[7] = 255;
    
    console.log("Pixels:", pixels);
        

    Common Mistakes and Pitfalls

    • Confusing normal arrays with typed arrays
    • Accessing out-of-bounds indexes
    • Not considering endianness when using DataView
    • Trying to push/pop — typed arrays have fixed length

    Best Practices

    • Use typed arrays only when performance is critical or working with binary data
    • Keep buffer sizes predictable and consistent
    • Use DataView for complex structures
    • Document data type assumptions clearly
    • Prefer Uint8ClampedArray for image pixel manipulation

    JS DOM Navigation

    DOM (Document Object Model) navigation allows JavaScript to traverse and manipulate HTML elements in a web page. It’s essential for dynamic content updates, event handling, and building interactive interfaces.

    Key Concepts

    • Document object and its properties
    • Traversing nodes: parentNode, childNodes, firstChild, lastChild
    • Element selection: getElementById, getElementsByClassName, querySelector, querySelectorAll
    • Sibling navigation: nextSibling, previousSibling
    • Node types: element, text, comment
    • Manipulating inner content: innerHTML, textContent

    The DOM represents HTML as a tree of nodes. Each element, attribute, and piece of text is a node. JavaScript can traverse these nodes to access or modify content.

    Node navigation methods allow moving between parents, children, and siblings. Element selectors like getElementById or querySelectorAll are commonly used to target specific elements. Once selected, properties like innerHTML and textContent allow you to read or update content dynamically.

    Syntax / Code Snippets

    
    // Selecting elements
    let header = document.getElementById("main-header");
    let buttons = document.getElementsByClassName("btn");
    let firstButton = document.querySelector(".btn");
    let allButtons = document.querySelectorAll(".btn");
    
    // Traversing nodes
    let parent = header.parentNode;
    let firstChild = header.firstChild;
    let nextSibling = header.nextSibling;
    
    // Manipulating content
    header.innerHTML = "Welcome to LearnX";
    console.log(firstButton.textContent);
        
    Example
    
    // Example: traverse and update DOM
    let container = document.getElementById("container");
    console.log("Parent node:", container.parentNode);
    
    let firstItem = container.firstChild;
    console.log("First child node:", firstItem);
    
    let items = document.querySelectorAll(".item");
    items.forEach((el, index) => {
      el.textContent = `Item ${index + 1} updated`;
    });
        
    Live Editor

    Real-World Use Case / Mini-Project

    Create a dynamic list that updates content when a button is clicked:

    
    let addButton = document.getElementById("add-btn");
    let list = document.getElementById("list");
    
    addButton.addEventListener("click", () => {
      let newItem = document.createElement("li");
      newItem.textContent = `New item ${list.children.length + 1}`;
      list.appendChild(newItem);
    });
        

    Common Mistakes and Pitfalls

    • Confusing node types (text vs element)
    • Using childNodes when children is intended
    • Modifying DOM before it is fully loaded
    • Forgetting to loop over NodeList returned by querySelectorAll

    Best Practices

    • Use document.querySelector or querySelectorAll for modern, flexible selection
    • Prefer children over childNodes for element nodes only
    • Wait for DOMContentLoaded before manipulating DOM
    • Minimize DOM access inside loops for performance
    • Use createElement and appendChild for dynamic content

    JS Windows

    The Window object represents the browser window in JavaScript. It is the global object in client-side scripts and provides access to the DOM, browser APIs, timers, and more.

    Key Concepts

    • Global object in the browser
    • Window properties: innerWidth, innerHeight, location, navigator
    • Timers: setTimeout, setInterval, clearTimeout, clearInterval
    • Dialogs: alert, confirm, prompt
    • Opening and closing windows: window.open, window.close
    • Scrolling and resizing: scrollTo, scrollBy, resizeTo

    The Window object is the top-level object representing the browser tab or window. It provides properties and methods to control the window, interact with the user, and access browser features. All global variables and functions are properties of the window object.

    Timers allow executing code after a delay or repeatedly. Dialog methods provide simple user interaction, while location and navigator objects give information about the URL, browser, and platform.

    Syntax / Code Snippets

    
    // Window properties
    console.log(window.innerWidth);
    console.log(window.innerHeight);
    console.log(window.location.href);
    
    // Dialogs
    alert("Hello, LearnX!");
    let confirmed = confirm("Do you want to continue?");
    let name = prompt("Enter your name:");
    
    // Timers
    let timer = setTimeout(() => console.log("Executed after 2s"), 2000);
    clearTimeout(timer);
    
    // Open new window
    let newWin = window.open("https://learnx.com", "_blank", "width=400,height=400");
    newWin.close();
        
    Example
    
    // Example: timer and alert
    function greetUser() {
      alert("Welcome to LearnX!");
    }
    
    setTimeout(greetUser, 1000);
    
    // Example: get window size
    console.log("Width:", window.innerWidth, "Height:", window.innerHeight);
    
    // Open a small popup window
    let popup = window.open("", "popup", "width=300,height=200");
    popup.document.write("

    Hello from popup!

    "); setTimeout(() => popup.close(), 3000);
    Live Editor

    Real-World Use Case / Mini-Project

    Create a countdown popup notification:

    
    let countdown = 5;
    let popupWin = window.open("", "countdown", "width=300,height=150");
    let interval = setInterval(() => {
      popupWin.document.body.innerHTML = `

    Closing in ${countdown} seconds

    `; countdown--; if(countdown < 0) { clearInterval(interval); popupWin.close(); } }, 1000);

    Common Mistakes and Pitfalls

    • Using alert excessively (blocks UI)
    • Forgetting to clear timers with clearTimeout or clearInterval
    • Assuming window.open will always succeed (blocked by popup blockers)
    • Mixing window size calculations with CSS viewport units

    Best Practices

    • Minimize blocking dialogs like alert
    • Always clear timers when no longer needed
    • Use window.innerWidth and innerHeight for responsive calculations
    • Test popup behavior across browsers
    • Use window methods judiciously to avoid user frustration

    JS Web APIs

    JavaScript Web APIs provide interfaces to interact with browser features such as DOM, Fetch, Geolocation, Storage, Canvas, and more. They extend JS capabilities beyond the core language.

    Key Concepts

    • Document Object Model (DOM)
    • Fetch API for HTTP requests
    • LocalStorage and SessionStorage
    • Geolocation API
    • Canvas API for graphics
    • Audio and Video APIs
    • Web Workers and Notifications

    Web APIs allow JavaScript to interact with browser-provided features. For example, the Fetch API enables network requests, LocalStorage stores key-value pairs locally, and the Canvas API allows drawing graphics programmatically. Each API provides a set of methods, properties, and events to control browser capabilities.

    Modern browsers provide standardized APIs, and developers can combine multiple APIs to create rich web applications, from interactive maps to multimedia players and offline apps.

    Syntax / Code Snippets

    
    // Fetch API example
    fetch("https://jsonplaceholder.typicode.com/todos/1")
      .then(response => response.json())
      .then(data => console.log(data))
      .catch(err => console.error(err));
    
    // LocalStorage example
    localStorage.setItem("username", "AK");
    console.log(localStorage.getItem("username"));
    
    // Geolocation example
    navigator.geolocation.getCurrentPosition(position => {
      console.log("Latitude:", position.coords.latitude);
      console.log("Longitude:", position.coords.longitude);
    });
    
    // Canvas API example
    let canvas = document.getElementById("myCanvas");
    let ctx = canvas.getContext("2d");
    ctx.fillStyle = "blue";
    ctx.fillRect(10, 10, 100, 50);
        
    Example
    
    // Using LocalStorage and Fetch API
    localStorage.setItem("user", "AK LearnX");
    
    let storedUser = localStorage.getItem("user");
    console.log("Stored user:", storedUser);
    
    fetch("https://jsonplaceholder.typicode.com/posts/1")
      .then(response => response.json())
      .then(post => console.log("Fetched post:", post))
      .catch(err => console.error(err));
        
    Live Editor

    Real-World Use Case / Mini-Project

    Build a simple geolocation-based greeting:

    
    navigator.geolocation.getCurrentPosition(position => {
      let lat = position.coords.latitude;
      let lon = position.coords.longitude;
      document.body.innerHTML = `

    Welcome! Your location is (${lat.toFixed(2)}, ${lon.toFixed(2)})

    `; });

    Common Mistakes and Pitfalls

    • Not handling asynchronous behavior correctly (e.g., Fetch API)
    • Forgetting permissions for Geolocation or Notifications
    • Assuming LocalStorage is always available
    • Ignoring browser compatibility for specific APIs

    Best Practices

    • Always check for API availability (feature detection)
    • Handle errors and permissions gracefully
    • Use asynchronous APIs properly with Promises or async/await
    • Minimize synchronous DOM updates in performance-critical code
    • Document which APIs are used and why

    JS AJAX

    AJAX (Asynchronous JavaScript and XML) allows web pages to communicate with servers without reloading the page. Modern AJAX often uses JSON instead of XML for data exchange, enabling dynamic and responsive web applications.

    Key Concepts

    • XMLHttpRequest (traditional method)
    • Fetch API (modern approach)
    • Asynchronous communication
    • Handling responses and errors
    • JSON as a preferred data format
    • Updating DOM without page reload

    AJAX allows sending HTTP requests to the server and handling the response dynamically. The traditional method uses XMLHttpRequest, but the Fetch API is modern, promise-based, and cleaner. JSON is typically used for data interchange because it’s lightweight and easy to parse.

    AJAX is fundamental for single-page applications (SPAs), form submissions, and live content updates like news feeds or chat messages. By keeping the page interactive without reloads, user experience improves significantly.

    Syntax / Code Snippets

    
    // XMLHttpRequest example
    let xhr = new XMLHttpRequest();
    xhr.open("GET", "https://jsonplaceholder.typicode.com/posts/1", true);
    xhr.onload = function() {
      if(xhr.status === 200) {
        console.log(JSON.parse(xhr.responseText));
      }
    };
    xhr.send();
    
    // Fetch API example
    fetch("https://jsonplaceholder.typicode.com/posts/1")
      .then(response => response.json())
      .then(data => console.log(data))
      .catch(err => console.error(err));
    
    // Async/Await
    async function getPost() {
      try {
        let response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
        let data = await response.json();
        console.log(data);
      } catch(error) {
        console.error(error);
      }
    }
    getPost();
        
    Example
    
    // Fetch API to update page content
    fetch("https://jsonplaceholder.typicode.com/users/1")
      .then(res => res.json())
      .then(user => {
        document.body.innerHTML = `

    User: ${user.name}

    Email: ${user.email}

    `; }) .catch(err => console.error("Error fetching user:", err));
    Live Editor

    Real-World Use Case / Mini-Project

    Load a list of posts dynamically without page reload:

    
    async function loadPosts() {
      try {
        let response = await fetch("https://jsonplaceholder.typicode.com/posts");
        let posts = await response.json();
        let container = document.createElement("div");
        posts.slice(0,5).forEach(post => {
          let div = document.createElement("div");
          div.innerHTML = `

    ${post.title}

    ${post.body}

    `; container.appendChild(div); }); document.body.appendChild(container); } catch(err) { console.error("Error loading posts:", err); } } loadPosts();

    Common Mistakes and Pitfalls

    • Not handling errors properly
    • Assuming synchronous execution (AJAX is asynchronous)
    • Forgetting to parse JSON responses
    • Not updating the DOM safely after fetching data

    Best Practices

    • Prefer Fetch API over XMLHttpRequest for modern applications
    • Always handle network errors
    • Use async/await for clean, readable code
    • Minimize DOM updates in loops for performance
    • Cache frequently fetched data when appropriate

    JS JSON

    JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is widely used to transmit data between a server and a client, and is easy for humans to read and write as well as for machines to parse and generate.

    Key Concepts

    • JSON syntax: objects, arrays, strings, numbers, booleans, null
    • Converting between JSON and JavaScript objects
    • Methods: JSON.stringify() and JSON.parse()
    • Use in AJAX / Fetch API
    • Data validation and error handling
    • Storage and configuration in web applications

    JSON represents structured data as text, using a format similar to JavaScript object literals. You can easily convert JavaScript objects to JSON strings using JSON.stringify() and parse JSON strings back to JavaScript objects using JSON.parse().

    JSON is language-independent, making it ideal for exchanging data between web applications, APIs, and servers. It is lightweight, human-readable, and widely supported across all modern programming environments.

    Syntax / Code Snippets

    
    // JavaScript object
    let user = { name: "AK", age: 25, skills: ["JS", "HTML", "CSS"] };
    
    // Convert to JSON string
    let jsonString = JSON.stringify(user);
    console.log(jsonString);
    
    // Convert JSON string back to JS object
    let parsedUser = JSON.parse(jsonString);
    console.log(parsedUser.name);
    console.log(parsedUser.skills[0]);
    
    // Using JSON in Fetch API
    fetch("https://jsonplaceholder.typicode.com/users/1")
      .then(response => response.json())
      .then(data => console.log(data));
        
    Example
    
    // Store data in localStorage as JSON
    let settings = { theme: "dark", notifications: true };
    localStorage.setItem("settings", JSON.stringify(settings));
    
    let storedSettings = JSON.parse(localStorage.getItem("settings"));
    console.log("Theme:", storedSettings.theme);
    console.log("Notifications enabled:", storedSettings.notifications);
        
    Live Editor

    Real-World Use Case / Mini-Project

    Save user preferences locally and load them on page load:

    
    // Save preferences
    let preferences = { fontSize: "16px", color: "blue" };
    localStorage.setItem("prefs", JSON.stringify(preferences));
    
    // Load preferences
    let prefs = JSON.parse(localStorage.getItem("prefs"));
    document.body.style.fontSize = prefs.fontSize;
    document.body.style.color = prefs.color;
        

    Common Mistakes and Pitfalls

    • Trying to store objects directly in localStorage (must stringify)
    • Parsing invalid JSON strings
    • Confusing JSON.stringify() and JSON.parse()
    • Overwriting existing JSON data unintentionally

    Best Practices

    • Always validate JSON before parsing
    • Use descriptive keys in JSON objects
    • Keep JSON structure simple and consistent
    • Use JSON for data storage and network communication, not UI logic
    • Handle parsing errors with try/catch

    JS jQuery

    jQuery is a fast, small, and feature-rich JavaScript library. It simplifies HTML DOM traversal, event handling, animation, and AJAX calls, making web development easier and more concise.

    Key Concepts

    • DOM selection with $() syntax
    • Chaining methods for concise code
    • Event handling: .click(), .on(), .hover()
    • DOM manipulation: .html(), .text(), .append(), .remove()
    • AJAX: $.ajax(), $.get(), $.post()
    • Animations: .fadeIn(), .slideUp()

    jQuery simplifies JavaScript by providing cross-browser support, shorter syntax, and utility methods. It enables developers to select elements easily, attach event listeners, modify content, perform animations, and send AJAX requests without writing verbose code.

    Although modern JavaScript can handle most jQuery tasks, jQuery is still used in legacy projects and for quick prototyping due to its simplicity and widespread documentation.

    Syntax / Code Snippets

    
    // Select elements
    let header = $("#main-header");
    let items = $(".item");
    
    // Event handling
    $("#btn").click(function() {
      alert("Button clicked!");
    });
    
    // DOM manipulation
    $(".item").text("Updated text");
    $("#container").append("

    New paragraph

    "); // AJAX call $.get("https://jsonplaceholder.typicode.com/posts/1", function(data) { console.log(data); }); // Animation $("#box").fadeIn(1000).slideUp(2000);
    Example
    
    $(document).ready(function() {
      $("#btn").click(function() {
        $("#container").append("

    Button was clicked!

    "); $(".item").css("color", "red"); }); });
    Live Editor

    Real-World Use Case / Mini-Project

    Create a simple dynamic list that highlights items on click:

    
    $(document).ready(function() {
      $("#add-btn").click(function() {
        let newItem = $("
  • New Item
  • "); newItem.click(function() { $(this).toggleClass("highlight"); }); $("#list").append(newItem); }); });

    Common Mistakes and Pitfalls

    • Not including jQuery library before your script
    • Mixing jQuery selectors and vanilla JS inconsistently
    • Using outdated jQuery methods (check version)
    • Overusing animations that affect performance

    Best Practices

    • Use $(document).ready() to ensure DOM is loaded
    • Cache selectors when using them multiple times
    • Prefer chaining methods for concise code
    • Use jQuery for legacy support or rapid prototyping
    • Keep animations smooth and minimal for performance

    JS Graphics

    JavaScript graphics involve rendering visual elements on the web using technologies like the Canvas API, SVG, and WebGL. This enables dynamic, interactive visualizations, animations, and games.

    Key Concepts

    • Canvas API for 2D rendering
    • Drawing shapes: rectangles, circles, lines, paths
    • Filling and stroking shapes
    • Text rendering on canvas
    • Using colors, gradients, and patterns
    • Animation using requestAnimationFrame()
    • SVG for scalable vector graphics
    • WebGL for 3D graphics (optional advanced)

    The Canvas API provides a <canvas> element where you can draw graphics programmatically. You can render shapes, images, and text, and combine them with JavaScript for animation and interactivity.

    For more advanced graphics, SVG provides scalable vector graphics, while WebGL enables GPU-accelerated 3D rendering. Combining these technologies allows you to create games, visualizations, charts, and interactive web content.

    Syntax / Code Snippets

    
    // Get canvas context
    let canvas = document.getElementById("myCanvas");
    let ctx = canvas.getContext("2d");
    
    // Draw rectangle
    ctx.fillStyle = "blue";
    ctx.fillRect(10, 10, 150, 100);
    
    // Draw circle
    ctx.beginPath();
    ctx.arc(100, 100, 50, 0, 2 * Math.PI);
    ctx.fillStyle = "red";
    ctx.fill();
    
    // Draw line
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(200, 200);
    ctx.strokeStyle = "green";
    ctx.stroke();
    
    // Text
    ctx.font = "20px Arial";
    ctx.fillStyle = "black";
    ctx.fillText("Hello LearnX!", 50, 50);
        
    Example
    
    // Simple animation using requestAnimationFrame
    let canvas = document.getElementById("myCanvas");
    let ctx = canvas.getContext("2d");
    let x = 0;
    
    function animate() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.fillStyle = "purple";
      ctx.fillRect(x, 50, 50, 50);
      x += 2;
      if (x > canvas.width) x = -50;
      requestAnimationFrame(animate);
    }
    animate();
        
    Live Editor

    Real-World Use Case / Mini-Project

    Create a bouncing ball animation:

    
    let ballX = 50, ballY = 50, dx = 3, dy = 2;
    let radius = 20;
    
    function bounceBall() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.beginPath();
      ctx.arc(ballX, ballY, radius, 0, 2*Math.PI);
      ctx.fillStyle = "orange";
      ctx.fill();
    
      if(ballX + radius > canvas.width || ballX - radius < 0) dx = -dx;
      if(ballY + radius > canvas.height || ballY - radius < 0) dy = -dy;
    
      ballX += dx;
      ballY += dy;
    
      requestAnimationFrame(bounceBall);
    }
    bounceBall();
        

    Common Mistakes and Pitfalls

    • Not clearing canvas each frame for animations
    • Using inefficient loops instead of requestAnimationFrame
    • Ignoring canvas size and scaling issues
    • Overdrawing or using too many elements that hurt performance

    Best Practices

    • Use requestAnimationFrame for smooth animations
    • Clear canvas before redrawing each frame
    • Cache frequently used elements or images
    • Keep drawing calculations minimal for performance
    • Use Canvas for 2D graphics; consider WebGL for complex 3D

    JS Examples

    This section provides practical JavaScript examples combining multiple concepts from beginner to advanced levels, including DOM manipulation, events, AJAX, JSON, and Canvas graphics.

    Key Concepts

    • Combining DOM manipulation, events, and forms
    • Using Fetch and JSON for dynamic content
    • Animation and graphics with Canvas
    • Timers and asynchronous operations
    • Practical real-world mini-projects

    Real-world JavaScript applications often combine multiple concepts. This section provides example projects demonstrating how to manipulate DOM elements, fetch data from APIs, handle user events, perform animations, and store data locally.

    These examples illustrate how modern JavaScript features (ES6+), asynchronous programming, and browser APIs can be combined to create responsive and interactive web applications.

    Syntax / Code Snippets

    
    // Example 1: Dynamic list with button click
    let addBtn = document.getElementById("add-btn");
    let list = document.getElementById("list");
    addBtn.addEventListener("click", () => {
      let li = document.createElement("li");
      li.textContent = `Item ${list.children.length + 1}`;
      list.appendChild(li);
    });
    
    // Example 2: Fetch and display user data
    async function loadUser() {
      let res = await fetch("https://jsonplaceholder.typicode.com/users/1");
      let user = await res.json();
      document.getElementById("user-info").innerHTML = `

    ${user.name}

    ${user.email}

    `; } loadUser(); // Example 3: Canvas animation let canvas = document.getElementById("myCanvas"); let ctx = canvas.getContext("2d"); let x = 0; function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "blue"; ctx.fillRect(x, 50, 50, 50); x = (x + 2) % canvas.width; requestAnimationFrame(animate); } animate();
    Example
    
    // Mini-project: To-Do List with localStorage
    const form = document.getElementById("todo-form");
    const input = document.getElementById("todo-input");
    const todoList = document.getElementById("todo-list");
    
    function loadTodos() {
      const todos = JSON.parse(localStorage.getItem("todos")) || [];
      todoList.innerHTML = "";
      todos.forEach(todo => {
        const li = document.createElement("li");
        li.textContent = todo;
        todoList.appendChild(li);
      });
    }
    
    form.addEventListener("submit", e => {
      e.preventDefault();
      let todos = JSON.parse(localStorage.getItem("todos")) || [];
      todos.push(input.value);
      localStorage.setItem("todos", JSON.stringify(todos));
      input.value = "";
      loadTodos();
    });
    
    loadTodos();
        
    Live Editor

    Real-World Use Case / Mini-Project

    This section demonstrates combining multiple JS concepts into functional web apps:

    • Interactive To-Do list with localStorage persistence
    • Fetching user and post data via API and dynamically updating DOM
    • Animating elements with Canvas for dashboards or games
    • Dynamic forms with validation and event handling

    Common Mistakes and Pitfalls

    • Not clearing DOM elements before rendering new content
    • Forgetting to handle asynchronous operations
    • Mixing vanilla JS and libraries inconsistently
    • Ignoring localStorage size limits and exceptions

    Best Practices

    • Modularize code into functions and reusable components
    • Use async/await for readability in asynchronous tasks
    • Validate and sanitize user inputs
    • Cache DOM selectors when used multiple times
    • Test interactive features across multiple browsers

    JS Reference

    The JS Reference section provides a concise, organized lookup for all JavaScript objects, methods, properties, and common utilities. It serves as a quick-access guide for developers to use while coding.

    Key Concepts

    • Global Objects: window, document, console
    • Data Types: String, Number, Boolean, Array, Object, Set, Map
    • Functions: function, arrow functions, async/await
    • DOM: getElementById, querySelector, appendChild, innerHTML
    • Events: addEventListener, removeEventListener, event object
    • Web APIs: Fetch, LocalStorage, SessionStorage, Geolocation, Canvas
    • ES6+ Features: let, const, template literals, destructuring, spread/rest, modules
    • Timers: setTimeout, setInterval, clearTimeout, clearInterval
    • Error Handling: try/catch, throw, finally
    • Regular Expressions: RegExp, test(), match(), replace()

    This reference acts as a one-stop guide to all core and advanced JavaScript constructs. It lists commonly used methods, properties, and patterns, along with examples for quick understanding. Developers can consult this section for syntax reminders, method usage, and feature support.

    It also includes notes on modern ES6+ features, browser APIs, and best practices to ensure code is efficient, readable, and maintainable.

    Syntax / Code Snippets

    
    // Arrays
    let arr = [1,2,3];
    arr.push(4);
    arr.pop();
    arr.forEach(item => console.log(item));
    
    // Objects
    let obj = {name: "AK", age: 25};
    console.log(obj.name);
    obj.email = "ak@example.com";
    
    // String methods
    let str = "LearnX";
    console.log(str.length);
    console.log(str.toUpperCase());
    console.log(str.includes("X"));
    
    // Number methods
    let num = 3.1415;
    console.log(Math.round(num));
    console.log(Math.floor(num));
    console.log(Math.random());
    
    // Date
    let now = new Date();
    console.log(now.getFullYear());
    console.log(now.toLocaleString());
    
    // JSON
    let data = {id:1, title:"JS"};
    let jsonStr = JSON.stringify(data);
    let parsedData = JSON.parse(jsonStr);
    
    // Fetch API
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then(res => res.json())
      .then(posts => console.log(posts));
    
    // Canvas example
    let canvas = document.getElementById("myCanvas");
    let ctx = canvas.getContext("2d");
    ctx.fillStyle = "red";
    ctx.fillRect(10, 10, 100, 50);
        
    Quick Try-It Example
    
    // Quick JS Reference Example
    const user = {name:"AK", role:"Developer"};
    console.log(`User: ${user.name}, Role: ${user.role}`);
    
    let arr = [1,2,3];
    arr.push(4);
    console.log("Array:", arr);
    
    fetch("https://jsonplaceholder.typicode.com/todos/1")
      .then(res => res.json())
      .then(todo => console.log("Todo:", todo));
        
    Live Editor

    Real-World Use Case

    Use this reference as a coding companion for:

    • Quick DOM manipulations
    • Form validations and event handling
    • AJAX / API requests
    • Canvas and graphics projects
    • ES6+ modern syntax and utilities

    Common Mistakes

    • Confusing let, const, and var
    • Forgetting to parse JSON data
    • Not caching DOM elements
    • Overlooking asynchronous behavior
    • Ignoring browser compatibility for some APIs

    Best Practices

    • Always refer to documentation when using unfamiliar methods
    • Use consistent coding style and indentation
    • Leverage ES6+ features for cleaner, modern code
    • Modularize code for reusability
    • Test features across different browsers and devices

    🎉 Congratulations!

    You've completed the JavaScript module.