R
Rishtaara
Knowledge Hub
Technology & IT

JavaScript Fundamentals: Complete Guide

By Rishtaara Editorial Team120 min read
#JavaScript#DOM#Async#ES6#Fetch#Modules#Beginner

Full W3Schools-style JS syllabus — syntax to DOM, async, modules, Web APIs, legacy AJAX/jQuery notes, and a quiz project. Every topic with a real-life example.

JS HOME — what this course covers

This Rishtaara JavaScript course teaches you step by step — from your first console.log to DOM events.

JavaScript (JS) makes web pages alive. HTML is structure. CSS is style. JavaScript is action — buttons, forms, menus, and updates without reloading the page.

Real-life example: Learning JS is like learning to drive after you know how a car looks (HTML) and is painted (CSS). Now you make the car move.

  • Basics: syntax, types, operators, loops, functions
  • Strings, numbers, arrays, objects, dates
  • Errors, debugging, and clean code habits
  • DOM and events — connect JS to HTML
Tip: Open your browser console (F12 → Console tab) while reading. Type small code and see results instantly.

Introduction — what is JavaScript?

JavaScript is a programming language that runs in the browser. It can also run on servers with Node.js, but this course starts with browser JS.

Every major website — including Rishtaara — uses JavaScript for login forms, search, sliders, and live updates.

Real-life example: JavaScript is like the remote control for your TV. HTML/CSS built the TV screen. JS is the buttons that change channels and volume.

  • Runs in Chrome, Firefox, Safari, Edge
  • No install needed for browser practice
  • Works with HTML and CSS on the same page

Where To — how to add JavaScript to a page

You can write JS inside a <script> tag in HTML, or in a separate .js file linked with src. Put scripts at the end of <body> or use defer in <head>.

External files are best for real projects — one script.js can power many pages. async loads JS without waiting; defer waits until HTML is parsed.

Real-life example: Inline script is a sticky note on one page. External file is a rule book kept in a drawer — open the same book on any page.

For learning, putting <script> just before </body> is simple and safe. defer in <head> is the modern professional way.
Inline, external, defer, and async
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>My JS Page</title>
  <!-- defer: runs after HTML is ready, keeps order -->
  <script src="app.js" defer></script>
</head>
<body>
  <h1 id="title">Hello</h1>

  <!-- Inline script at bottom of body (also fine for learning) -->
  <script>
    console.log("Page loaded!");
  </script>
</body>
</html>
app.js (external file)
// This file is linked from HTML
console.log("Hello from app.js");

Output — showing results

console.log() prints to the browser DevTools console — use this every day while learning. innerHTML changes HTML inside an element.

document.write() and alert() exist but are mostly for demos. alert() blocks the whole page; avoid it on real sites like Rishtaara.

Real-life example: console.log is whispering to yourself in a diary only you see. innerHTML is changing the text on a shop signboard for everyone.

Four ways to output
// 1. Console (best for learning and debugging)
console.log("Welcome to Rishtaara!");

// 2. Change HTML content
document.getElementById("title").innerHTML = "Hello, Rishtaara!";

// 3. document.write — overwrites page if used late (avoid)
// document.write("Old-style output");

// 4. alert — popup box (OK for tiny demos only)
// alert("Hello!");

JavaScript Syntax

JavaScript programs are made of statements. Each statement is one instruction, usually ending with a semicolon (;).

JavaScript is case-sensitive — name and Name are different. Spaces and line breaks are mostly ignored.

Real-life example: Statements are like steps in a recipe. Step 1: boil water. Step 2: add tea. Order matters.

Basic statements
let cups = 2;
cups = cups + 1;
console.log(cups); // 3

Comments

Comments are notes for humans. The computer skips them. Use // for one line and /* ... */ for many lines.

Real-life example: Comments are like pencil notes in your textbook margin — they help you remember, but the teacher ignores them in the exam.

Write comments when the code is not obvious. Do not comment every line — good variable names explain a lot.
Single-line and multi-line comments
// This is a single-line comment
let price = 100;

/*
  This comment
  spans many lines
*/
price = price + 50;

Identifiers — naming things

Identifiers are names for variables, functions, and objects. They can use letters, digits, _, and $. They cannot start with a digit.

Use camelCase for multi-word names: userName, totalPrice. Avoid reserved words like let, if, class as names.

Real-life example: An identifier is a name tag. "studentRoll42" is clear. "x" is a name tag with no info — hard to remember later.

Good and bad names
const userName = "Asha";   // good
const totalPrice = 499;     // good
// const 2name = "bad";     // Error — starts with digit

Data Types

JavaScript has primitive types (simple values) and objects (collections and complex data). typeof tells you the type.

Real-life example: Data types are like different containers — a water bottle (string), a weight scale reading (number), a yes/no switch (boolean).

  • string — text in quotes: "Hello"
  • number — integers and decimals: 42, 3.14
  • boolean — true or false
  • undefined — variable declared but no value yet
  • null — empty on purpose
  • bigint — very large whole numbers
  • symbol — unique identifier (advanced)
  • object — arrays, dates, plain objects, etc.
All main types
typeof "Rishtaara"     // "string"
typeof 42              // "number"
typeof true            // "boolean"
typeof undefined       // "undefined"
typeof null            // "object" (known quirk)
typeof 9007199254740991n // "bigint"
typeof Symbol("id")  // "symbol"
typeof { name: "A" } // "object"

Variables — let, const, and var

Variables store values. Use const when the value will not be reassigned. Use let when it will change. Avoid var in new code.

const does not freeze objects — you can change properties inside an object, but you cannot reassign the variable itself.

Real-life example: const is like your birth date — fixed. let is like today's temperature — it changes through the day.

Rule of thumb: start with const. Change to let only when you need to reassign.
let, const, and var
const siteName = "Rishtaara";
// siteName = "Other"; // Error — cannot reassign const

let score = 0;
score = score + 10; // OK with let

var oldStyle = "avoid in new code";
// var has function scope and hoisting quirks

Arithmetic Operators

Use +, -, *, /, and % (remainder) for math. + also joins strings: "Hello" + " World".

Real-life example: Arithmetic is like a shop calculator — add prices, subtract discount, multiply quantity, divide among friends.

Math and string join
let a = 10, b = 3;
console.log(a + b);  // 13
console.log(a % b);  // 1 (remainder)
console.log("Score: " + 100); // "Score: 100"

Assignment Operators

Assignment puts a value into a variable: =. Shorthand like +=, -=, *= saves typing.

Real-life example: += is like adding more rice to a pot — the pot still holds rice, just more than before.

Assignment shortcuts
let x = 5;
x += 3;  // same as x = x + 3 → 8
x *= 2;  // 16
x -= 4;  // 12

Comparison Operators

Comparisons return true or false: == loose equal, === strict equal (prefer this), !=, !==, >, <, >=, <=.

Always use === and !== so type and value both match. "5" === 5 is false.

Real-life example: === is checking both item name and weight at the shop. == only glances and sometimes guesses wrong.

Strict vs loose equality
5 == "5"   // true (loose — avoid)
5 === "5"  // false (strict — use this)
5 === 5    // true

Logical Operators

&& (AND) needs both true. || (OR) needs at least one true. ! (NOT) flips true to false.

Real-life example: To enter a cinema — you need a ticket AND an ID (&&). To get a discount — student OR senior (||).

AND, OR, NOT
const hasTicket = true;
const hasId = false;

console.log(hasTicket && hasId); // false
console.log(hasTicket || hasId); // true
console.log(!hasTicket);         // false

Ternary Operator

condition ? valueIfTrue : valueIfFalse — a short if/else in one line.

Real-life example: At a tea stall — "chai or coffee?" one question, one answer path.

Ternary example
const age = 20;
const label = age >= 18 ? "Adult" : "Minor";
console.log(label); // "Adult"

typeof Operator

typeof returns a string telling the type of a value. Useful while learning and debugging.

Real-life example: typeof is like checking a parcel label before opening — is it books or clothes?

typeof checks
typeof "hello"  // "string"
typeof 0        // "number"
typeof NaN      // "number" (NaN is still a number type)

Nullish Coalescing (??)

?? returns the right side only when the left is null or undefined — not for 0 or "".

Real-life example: If your nickname is not set (null), use your real name. If nickname is "" (empty string on purpose), keep it.

?? vs ||
const count = 0;
console.log(count || 10);  // 10 — wrong if 0 is valid
console.log(count ?? 10);  // 0 — correct

const name = null;
console.log(name ?? "Guest"); // "Guest"

Optional Chaining (?.)

?. safely reads nested properties. If something in the chain is null or undefined, it stops and returns undefined instead of crashing.

Real-life example: Asking for a friend's friend's phone — if your friend is missing, you stop politely instead of shouting at empty air.

?? and ?. are modern ES2020 tools. They make code safer when data might be missing — common in API responses.
Safe property access
const user = { profile: { city: "Delhi" } };
console.log(user.profile?.city);    // "Delhi"
console.log(user.address?.city);    // undefined (no crash)

const list = null;
console.log(list?.length);          // undefined

if Statement

if runs code only when a condition is true. Use it for decisions — login checks, age rules, empty cart warnings.

Real-life example: IF it is raining, THEN take an umbrella. Otherwise walk normally.

Simple if
const score = 85;
if (score >= 60) {
  console.log("Pass");
}

else and else if

else runs when the if condition is false. else if checks another condition when the first one failed.

Real-life example: IF marks >= 90 → A grade, ELSE IF >= 75 → B grade, ELSE → practice more.

if / else if / else
const marks = 72;
if (marks >= 90) {
  console.log("Grade A");
} else if (marks >= 75) {
  console.log("Grade B");
} else {
  console.log("Keep studying");
}

switch Statement

switch compares one value to many cases. Use break after each case or execution falls through to the next.

Real-life example: A vending machine button — press 1 for chai, 2 for coffee, default for water.

Use if/else for ranges (score >= 60). Use switch when comparing one variable to exact values (day === 3).
switch on day number
const day = 3;
switch (day) {
  case 1:
    console.log("Monday");
    break;
  case 2:
    console.log("Tuesday");
    break;
  case 3:
    console.log("Wednesday");
    break;
  default:
    console.log("Other day");
}

Truthy and Falsy Values

In conditions, JavaScript treats some values as false: false, 0, "", null, undefined, NaN. Everything else is truthy.

Real-life example: An empty wallet ("" or 0) means "no money" in a condition. A wallet with even 1 rupee is truthy.

Truthy / falsy in if
const name = "";
if (name) {
  console.log("Hello " + name);
} else {
  console.log("Please enter your name"); // runs
}

if ("Rishtaara") {
  console.log("Non-empty string is truthy"); // runs
}

for Loop

for repeats code a fixed number of times. It has start (let i = 0), condition (i < 5), and step (i++).

Real-life example: Counting laps in a running ground — start at 1, stop at 10, add 1 each lap.

Classic for loop
for (let i = 1; i <= 5; i++) {
  console.log("Lap " + i);
}

while Loop

while repeats while a condition is true. Check the condition before each round.

Real-life example: Keep filling water while the bottle is not full.

while loop
let count = 3;
while (count > 0) {
  console.log(count);
  count--;
}

do...while Loop

do...while runs the body at least once, then checks the condition.

Real-life example: Taste the soup once, then decide if you need more salt.

do while
let n = 0;
do {
  console.log(n);
  n++;
} while (n < 3);

for...of Loop

for...of loops over values in arrays, strings, and other iterables. Simple and readable.

Real-life example: Hand out one textbook to each student in a line — you take each item directly.

for...of with array
const fruits = ["apple", "mango", "banana"];
for (const fruit of fruits) {
  console.log(fruit);
}

for...in Loop

for...in loops over property names (keys) of an object. Avoid it on arrays — use for...of or forEach instead.

Real-life example: Reading labels on boxes in a storeroom — you get names of boxes, not the contents one by one.

for...in with object
const user = { name: "Asha", city: "Mumbai" };
for (const key in user) {
  console.log(key + ": " + user[key]);
}

break and continue

break exits the loop early. continue skips the rest of the current round and goes to the next.

Real-life example: break — stop searching when you find your keys. continue — skip one bad apple and check the next.

break and continue
for (let i = 1; i <= 10; i++) {
  if (i === 3) continue; // skip printing 3
  if (i === 8) break;    // stop at 8
  console.log(i);
}

String Basics

Strings are text inside single quotes ' ', double quotes " ", or backticks ` ` for template literals.

Real-life example: A string is a garland of letters — each character sits in order on the thread.

Three quote styles
const a = "Hello";
const b = 'World';
const c = `Hello ${b}`; // template literal
console.log(c); // "Hello World"

Template Literals

Backticks allow ${expression} inside strings — no messy + joining.

Real-life example: Filling a form letter — "Dear ${name}" auto-inserts the name instead of writing by hand.

Template literal
const name = "Asha";
const msg = `Welcome to Rishtaara, ${name}!`;
console.log(msg);

String Length

.length counts characters including spaces.

Real-life example: Counting beads on a necklace — each bead is one character.

length property
"hello".length;      // 5
"Rishtaara".length;  // 9

slice and substring

slice(start, end) cuts part of a string. substring is similar but handles negative indexes differently — prefer slice.

Real-life example: Cutting a piece of ribbon from meter 2 to meter 5.

slice
const text = "JavaScript";
console.log(text.slice(0, 4));  // "Java"
console.log(text.slice(4));     // "Script"

replace, split, and trim

replace swaps text (first match only unless you use replaceAll). split breaks into an array. trim removes spaces from start and end.

Real-life example: replace — white-out one word. split — cut a sentence into words. trim — shave extra foam off a soap bar.

replace, split, trim
"hello world".replace("world", "JS");
"a,b,c".split(",");           // ["a", "b", "c"]
"  hello  ".trim();           // "hello"

includes, toUpperCase, toLowerCase

includes checks if text contains a piece. toUpperCase and toLowerCase change letter case.

Real-life example: includes — search if a word exists in a paragraph. toUpperCase — shouting in ALL CAPS.

Strings are immutable — methods return a new string; they do not change the original.
Search and case
"Rishtaara".includes("Rish"); // true
"Hello".toUpperCase();          // "HELLO"
"Hello".toLowerCase();          // "hello"

JavaScript Numbers

All numbers in JS are stored as floating point — integers like 42 and decimals like 3.14 use the same type.

Real-life example: A weighing scale shows whole kg and grams on one display — one number line, many formats.

Integers and floats
const whole = 100;
const price = 99.99;
const big = 1e6; // 1000000

NaN and Infinity

NaN means Not a Number — bad math like "hello" * 2. Infinity is larger than any number — 1 / 0 gives Infinity.

Real-life example: NaN is asking "what is apple plus Tuesday?" — no valid answer. Infinity is a road with no end sign.

NaN and Infinity
"text" * 2;     // NaN
Number.isNaN(NaN); // true
1 / 0;          // Infinity
-1 / 0;         // -Infinity

Math.round, floor, ceil

Math.round goes to nearest integer. Math.floor rounds down. Math.ceil rounds up.

Real-life example: round — nearest rupee. floor — how many full boxes fit. ceil — minimum boxes to ship all items.

Rounding
Math.round(4.6);  // 5
Math.floor(4.9);  // 4
Math.ceil(4.1);   // 5

Math.random, max, min, abs

Math.random() gives 0 to less than 1. Math.max and Math.min pick largest/smallest. Math.abs removes minus sign.

Real-life example: random — rolling a dice. max/min — tallest and shortest student. abs — distance (always positive).

For money on Rishtaara-style apps, store paise as integers (4999 = ₹49.99) to avoid float rounding bugs.
Math utilities
Math.random();              // e.g. 0.734...
Math.floor(Math.random() * 6) + 1; // dice 1–6
Math.max(10, 25, 3);         // 25
Math.min(10, 25, 3);         // 3
Math.abs(-7);                // 7

Function Declaration

A function is a reusable block of code with a name. Call it with parentheses and arguments.

Real-life example: A function is a recipe card — write once, cook many times.

Function declaration
function greet(name) {
  return "Hello, " + name + "!";
}
console.log(greet("Asha")); // "Hello, Asha!"

Function Expression

Store a function in a variable. Often used when passing functions as values.

Real-life example: Same recipe card, but kept inside a folder labeled "myRecipe" instead of pinned on the wall.

Function expression
const add = function (a, b) {
  return a + b;
};
console.log(add(2, 3)); // 5

Arrow Functions

Short syntax: (params) => expression or => { statements }. Great for small callbacks.

Real-life example: A quick sticky note instead of a full recipe card — same job, less writing.

Arrow function
const double = (n) => n * 2;
const sum = (a, b) => {
  return a + b;
};
console.log(double(5)); // 10

Parameters, Return & Default Parameters

Parameters are inputs. return sends a value back. Default parameters fill in when an argument is missing.

Real-life example: A chai order — size defaults to "regular" if you say nothing.

Defaults and return
function makeChai(cups = 1, sugar = true) {
  return `${cups} cup(s), sugar: ${sugar}`;
}
console.log(makeChai());       // 1 cup(s), sugar: true
console.log(makeChai(2, false));

setTimeout and setInterval

setTimeout runs code once after a delay (milliseconds). setInterval repeats on a timer.

Real-life example: setTimeout — oven timer rings once. setInterval — a clock ticking every second.

Timers
// Run once after 2 seconds
const onceId = setTimeout(() => {
  console.log("2 seconds passed");
}, 2000);

// Run every 1 second
const repeatId = setInterval(() => {
  console.log("tick");
}, 1000);

clearTimeout and clearInterval

Save the timer id and pass it to clearTimeout or clearInterval to stop future runs.

Real-life example: Cancel the oven alarm before it rings if you already removed the cake.

Timers do not pause your whole page — JS keeps running other code. The browser calls your function when time is up.
Stopping timers
const id = setInterval(() => console.log("hi"), 500);
clearInterval(id); // stops the repeating timer
How timers fit the event loop

Object Literals

Objects store key-value pairs in { }. Keys are strings (or symbols); values can be any type.

Real-life example: A student file — name, roll, class — all details on one card.

Create an object
const user = {
  name: "Asha",
  age: 16,
  city: "Delhi",
};
console.log(user.name); // dot notation
console.log(user["city"]); // bracket notation

Properties and Methods

A property holds data. A method is a function inside an object.

Real-life example: A phone object — brand (property), call() (method you can use).

Method on object
const calc = {
  brand: "Simple",
  add(a, b) {
    return a + b;
  },
};
console.log(calc.add(2, 3)); // 5

this (brief)

Inside a method, this refers to the object that owns the method.

Real-life example: When you say "my phone", "my" points to you — this points to the object calling the method.

this in a method
const shop = {
  name: "Rishtaara",
  welcome() {
    return "Welcome to " + this.name;
  },
};
console.log(shop.welcome());

Scope — global, function, block

Scope is where a variable can be used. Global — whole program. Function — inside that function. Block — inside { } with let/const.

Real-life example: Global = school notice board (everyone sees). Function = one classroom diary. Block = one desk drawer.

Scopes
const globalVar = "everywhere";

function demo() {
  const fnVar = "inside function";
  if (true) {
    const blockVar = "inside block";
    console.log(blockVar); // OK
  }
  // console.log(blockVar); // Error
}

Hoisting (brief)

var declarations and function declarations are moved to the top of their scope in memory — but only var is initialized as undefined until the line runs.

let and const are hoisted but not usable before the line — Temporal Dead Zone.

Real-life example: Hoisting is like reserving a seat name before the person sits — var seat exists empty early; let seat is locked until arrival.

Use const/let and write code top-to-bottom. Do not rely on hoisting tricks in real projects.
Hoisting behavior
console.log(x); // undefined (var hoisted)
var x = 5;

// console.log(y); // Error — let not initialized yet
let y = 10;

Creating Dates

Use new Date() for now, new Date("2026-07-24"), or new Date(year, monthIndex, day). Month index starts at 0 — January is 0.

Real-life example: new Date() is looking at today's calendar on the wall right now.

New Date examples
const now = new Date();
const fixed = new Date("2026-07-24");
const parts = new Date(2026, 6, 24); // month 6 = July

Getting Date Parts

Methods like getFullYear(), getMonth(), getDate(), getDay(), getHours() read parts of a date.

Real-life example: Reading day, month, year from a paper calendar one field at a time.

Get methods
const d = new Date();
d.getFullYear();  // e.g. 2026
d.getMonth();     // 0–11
d.getDate();      // day of month
d.getDay();       // 0=Sunday … 6=Saturday

Formatting Dates

toDateString(), toISOString(), and toLocaleDateString() turn a Date into readable text.

Real-life example: Same birthday written as "24 Jul 2026" or "2026-07-24" — different formats, same day.

Format output
const d = new Date("2026-07-24");
d.toDateString();                    // "Fri Jul 24 2026"
d.toISOString();                     // UTC string
d.toLocaleDateString("en-IN");       // Indian format

Temporal API — what and why

The Temporal API is a modern replacement for Date. It fixes timezone bugs and makes date math clearer (PlainDate, ZonedDateTime).

Browser support is still growing — check Can I Use before production. Learn Date first; Temporal is the future.

Real-life example: Old Date is a broken wall clock with no city label. Temporal is a clock that knows Delhi vs London time clearly.

Tip: Store dates in ISO format (2026-07-24) in databases. Convert to local text only when showing users on Rishtaara.
Temporal concept (when supported)
// Future-friendly style (needs Temporal in browser)
// const today = Temporal.Now.plainDateISO();
// const meeting = Temporal.PlainDate.from("2026-07-24");
// today.until(meeting).days; // days until meeting

// For now, Date + toLocaleString works everywhere:
const event = new Date("2026-07-24T10:00:00");
console.log(event.toLocaleString("en-IN"));

Creating and Indexing Arrays

Arrays hold ordered lists: const arr = [1, 2, 3]. Index starts at 0 — arr[0] is first item.

Real-life example: A numbered queue at a ticket counter — position 0 is first in line.

Array basics
const colors = ["red", "green", "blue"];
console.log(colors[0]);  // "red"
console.log(colors.length); // 3

push, pop, shift, unshift

push adds to end. pop removes from end. shift removes from start. unshift adds to start.

Real-life example: push/pop — people joining or leaving the back of a line. shift/unshift — front of the line.

Add and remove
const list = ["a", "b"];
list.push("c");     // ["a","b","c"]
list.pop();         // removes "c"
list.unshift("z");  // ["z","a","b"]
list.shift();       // removes "z"

splice and slice

splice changes the array (add/remove items). slice copies a piece without changing the original.

Real-life example: splice — edit the original notebook page. slice — photocopy one page.

splice vs slice
const nums = [1, 2, 3, 4];
nums.splice(1, 1, 99); // remove 1 item at index 1, insert 99
// nums is now [1, 99, 3, 4]

const part = [1, 2, 3, 4].slice(1, 3); // [2, 3] — original unchanged

map, filter, find

map transforms each item. filter keeps items that pass a test. find returns the first match.

Real-life example: map — repack every item in new wrapping. filter — keep only ripe mangoes. find — first student with roll 42.

Transform and search
const prices = [100, 200, 300];
const withTax = prices.map((p) => p * 1.18);
const big = prices.filter((p) => p >= 200);
const first = prices.find((p) => p > 150); // 200

includes and spread (...)

includes checks if a value exists. Spread ... copies or merges arrays.

Real-life example: includes — "Is mango in the fruit basket?" Spread — pour two baskets into one bigger basket.

includes and spread
[1, 2, 3].includes(2); // true

const a = [1, 2];
const b = [3, 4];
const merged = [...a, ...b]; // [1, 2, 3, 4]

Sets — unique values only

A Set stores each value once. Duplicates are ignored. Good for unique tags, visited pages, or deduplication.

Real-life example: A Set is a guest list where each name appears only once — no duplicate entries.

Set basics
const tags = new Set(["js", "html", "js", "css"]);
console.log(tags.size); // 3 — duplicate "js" dropped
tags.add("react");
tags.has("html"); // true

Set operations

add, delete, has, clear, and for...of loop over a Set.

Real-life example: add — write a new name on the list. delete — cross one name off.

Working with Set
const ids = new Set([1, 2, 3]);
ids.delete(2);
for (const id of ids) {
  console.log(id);
}

Maps — key-value with any key

Map is like an object but keys can be any type — objects, numbers, strings. Keeps insertion order.

Real-life example: A Map is a locker room — locker number (key) can be string or number, each holds one bag (value).

Map basics
const scores = new Map();
scores.set("Asha", 95);
scores.set("Ravi", 88);
console.log(scores.get("Asha")); // 95
console.log(scores.size);        // 2

Map vs plain object

Use Map when keys are unknown or not strings, or when you need size and frequent add/delete. Plain {} is fine for fixed JSON-like data.

Real-life example: Object = fixed form with name, age fields. Map = dynamic sticky notes you add anytime.

Convert array to unique list: [...new Set(myArray)] — very common one-liner.
Map with object key
const user = { id: 1 };
const cache = new Map();
cache.set(user, { lastLogin: "2026-07-24" });
console.log(cache.get(user));

forEach

forEach runs a function for each array item. It does not return a new array — use map for that.

Real-life example: Calling each student name from attendance sheet — read only, no new list.

forEach
["apple", "mango"].forEach((fruit, index) => {
  console.log(index, fruit);
});

map, filter, reduce

map — new array with changes. filter — new array with matches. reduce — fold all items into one value (sum, max, object).

Real-life example: reduce — add all bill amounts into one total at month end.

reduce total
const bills = [100, 250, 75];
const total = bills.reduce((sum, bill) => sum + bill, 0);
console.log(total); // 425

some and every

some — true if at least one item passes. every — true if all items pass.

Real-life example: some — at least one egg is broken. every — all eggs are fresh.

some and every
[1, 2, 3].some((n) => n > 2);   // true
[1, 2, 3].every((n) => n > 0);  // true
[1, 2, 3].every((n) => n > 1);  // false

RegExp — patterns in text

Regular expressions match patterns in strings. Write /pattern/ or new RegExp("pattern").

Real-life example: RegExp is a stencil — only text that fits the hole shape is selected.

Create RegExp
const pattern = /hello/i; // i = ignore case
pattern.test("Hello World"); // true

test and match

test returns true/false. match returns matched parts or null.

Real-life example: test — "Does this look like an email?" match — "Show me the phone number part."

test and match
/\d+/.test("Room 42");     // true — has digits
"Price: 499".match(/\d+/);    // ["499"]

Common patterns — email and digits

Simple checks: email has @ and dot; digits use \d. Real validation needs stricter rules, but these help in learning.

Real-life example: Email pattern is a basic gate check at school entry — not full security, but catches obvious mistakes.

Do not over-trust regex alone for payments or login — always validate on server too.
Email and digits
const email = "user@rishtaara.com";
const emailOk = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);

const phone = "9876543210";
const allDigits = /^\d{10}$/.test(phone);

try, catch, finally

try runs risky code. catch handles errors. finally always runs — good for cleanup.

Real-life example: try — cook carefully. catch — if milk spills, wipe floor. finally — turn off gas either way.

Error handling
try {
  const data = JSON.parse('{"ok":true}');
  console.log(data.ok);
} catch (err) {
  console.log("Bad JSON:", err.message);
} finally {
  console.log("Done trying");
}

throw

throw creates your own error when something is wrong — bad input, missing field.

Real-life example: throw — refuse to serve if the order has no item name.

Throw custom error
function divide(a, b) {
  if (b === 0) {
    throw new Error("Cannot divide by zero");
  }
  return a / b;
}

Debugging with console

Use console.log, console.table, and console.error. Read red error messages — they show file and line number.

Real-life example: console.log is leaving breadcrumbs on a path so you know where you walked.

Console helpers
const users = [{ name: "A" }, { name: "B" }];
console.table(users);
console.error("Something went wrong");

Breakpoints (idea)

In DevTools (F12 → Sources), click a line number to pause code there. Step line by line and inspect variables.

Real-life example: Pause a movie frame by frame to see exactly what happened before the bug.

  • F12 → Sources tab → open your .js file
  • Click line number for blue breakpoint
  • Refresh page — code stops at that line
  • Use Step Over to go line by line

Style Guide — naming, semicolons, const-first

Use clear camelCase names. End statements with semicolons for safety. Prefer const, then let. Use 2-space indent.

Real-life example: Clean code is a neat shop shelf — customers (and you next month) find things fast.

Clean style
const MAX_USERS = 100; // constants often UPPER_SNAKE
const userName = "asha"; // camelCase for variables

function getTotal(items) {
  return items.reduce((sum, x) => sum + x, 0);
}

JavaScript Versions — ES5 and ES6+

ES5 (2009) — older baseline. ES6 / ES2015+ — let/const, arrow functions, classes, modules, and more. Modern browsers support ES6+ well.

Real-life example: ES5 is an old textbook edition. ES6+ is the updated book with clearer chapters — learn the new edition.

  • ES5: var, function, classic syntax
  • ES6+: let, const, arrow, template literals, destructuring
  • New features arrive yearly (ES2017, ES2020 with ?? and ?.)

Reference — MDN

MDN Web Docs (developer.mozilla.org) is the best free reference for JavaScript. Search any method — Array.map, Date, fetch.

Real-life example: MDN is a dictionary for programmers — look up any word (function) when you forget spelling or meaning.

Bookmark MDN for JavaScript and keep this Rishtaara course for guided learning in simple English.

HTML First — JS and HTML together

JavaScript connects to HTML through the DOM (Document Object Model). The browser turns HTML into a tree of objects JS can read and change.

Real-life example: HTML builds the shop. JavaScript is the shopkeeper who changes prices and opens doors when customers click.

HTML page ready for JS
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Rishtaara Demo</title>
</head>
<body>
  <h1 id="title">Welcome</h1>
  <button id="btn">Click me</button>
  <script src="app.js" defer></script>
</body>
</html>

HTML DOM — getElementById and querySelector

getElementById finds one element by id. querySelector uses CSS selectors — more flexible (#id, .class, button).

Real-life example: getElementById is finding a student by exact roll number. querySelector is finding "any boy in blue shirt."

Select elements
const title = document.getElementById("title");
const btn = document.querySelector("#btn");
const firstP = document.querySelector("p");

textContent and classList

textContent sets plain text inside an element. classList.add/remove/toggle changes CSS classes.

Real-life example: textContent — change the words on a sign. classList — add "highlight" sticker without rewriting whole sign.

Change text and classes
const el = document.querySelector("#title");
el.textContent = "Hello, Rishtaara!";
el.classList.add("big-title");
el.classList.toggle("hidden");

createElement and append

document.createElement makes a new tag. append or appendChild adds it to the page.

Real-life example: createElement — build a new chair. append — place the chair in the room.

Add new element
const li = document.createElement("li");
li.textContent = "New item";
document.querySelector("ul").append(li);

HTML Events — onclick

Events are user actions — click, type, submit. onclick in HTML works but addEventListener in JS is cleaner.

Real-life example: onclick attribute is a doorbell wired in the wall. addEventListener is a wireless bell you attach anytime.

Inline onclick (learning only)
<button onclick="alert('Hi')">Say Hi</button>

addEventListener

element.addEventListener("click", handler) runs your function when the event happens. You can add many listeners.

Real-life example: One door, many listeners — security camera and welcome music both react to the same door opening.

Click listener
const btn = document.querySelector("#btn");
btn.addEventListener("click", () => {
  console.log("Button clicked!");
});

input and submit events

input fires as the user types. submit fires when a form is sent — use event.preventDefault() to stop page reload for JS handling.

Real-life example: input — live typing on WhatsApp. submit — pressing Send on a form; preventDefault keeps you on the same page.

You finished JS basics! Next steps: async/fetch, modules, and a framework like React in later Rishtaara courses.
Form input and submit
const input = document.querySelector("#name");
input.addEventListener("input", (e) => {
  console.log("Typing:", e.target.value);
});

const form = document.querySelector("#signup");
form.addEventListener("submit", (e) => {
  e.preventDefault();
  console.log("Form handled by JS — no reload");
});
Matching HTML form
<form id="signup">
  <input id="name" type="text" placeholder="Your name" />
  <button type="submit">Join Rishtaara</button>
</form>

Closures

A closure happens when an inner function remembers variables from the outer function, even after the outer function has finished.

This is useful for private data, counters, and factory functions.

Real-life example: A bank locker keeps your items safe inside. Only your key (inner function) can open it — outsiders cannot see what is inside.

Closure — private counter
function makeCounter(start = 0) {
  let count = start; // "private" — not visible outside
  return {
    add() { count++; return count; },
    get() { return count; },
  };
}

const score = makeCounter(10);
score.add(); // 11
score.add(); // 12
// score.count — undefined (protected)

Callbacks

A callback is a function you pass to another function. It runs later — after a click, a timer, or when data arrives.

Real-life example: You order food and give your phone number (callback). The restaurant calls you when the order is ready — you do not stand at the counter forever.

Callback after button click
function showMessage(message, callback) {
  console.log(message);
  callback();
}

document.querySelector("#btn").addEventListener("click", () => {
  showMessage("Lesson saved!", () => {
    alert("Great job on Rishtaara!");
  });
});

Rest and spread parameters

Rest (...args) collects extra arguments into an array. Spread (...arr) expands an array or object into separate items.

Real-life example: Rest is like putting loose coins into one pouch. Spread is like pouring that pouch back out onto the table one coin at a time.

Rest and spread
function sum(...numbers) {
  return numbers.reduce((total, n) => total + n, 0);
}
sum(2, 3, 5); // 10

const scores = [85, 92, 78];
const allScores = [70, ...scores, 95]; // [70, 85, 92, 78, 95]

const user = { name: "Asha", grade: 10 };
const updated = { ...user, grade: 11 }; // clone + change one field

IIFE (Immediately Invoked Function Expression)

An IIFE is a function that runs right away. It creates its own scope so variables do not leak into the global space.

Modern code uses modules instead, but you will still see IIFEs in older scripts.

Real-life example: A pop-up stall opens, sells snacks, and closes — all in one day. It does its job once and leaves no mess behind.

IIFE — run once, stay private
(function () {
  const secretKey = "abc123";
  console.log("App started with key:", secretKey);
})();

// secretKey is not available here — good for avoiding name clashes

Higher-order functions

A higher-order function takes another function as an argument, returns a function, or both. Array methods like map, filter, and reduce are higher-order functions.

Real-life example: A teacher (higher-order function) gives homework to students (functions). The teacher decides when and how each student works.

map, filter, reduce
const prices = [100, 250, 80];

const withTax = prices.map(p => p * 1.18);
const bigOnes = prices.filter(p => p >= 100);
const total = prices.reduce((sum, p) => sum + p, 0);

console.log(withTax);  // [118, 295, 94.4]
console.log(bigOnes);  // [100, 250]
console.log(total);    // 430

call, apply, and bind (brief)

These methods control what this points to inside a function. call and apply run the function right away; bind returns a new function with this fixed.

Real-life example: Borrowing a friend's bike (call/apply) means you ride it today with their name on the register. bind is like getting a spare key — same bike, same owner, ready anytime.

call, apply, bind
const person = {
  name: "Ravi",
  greet(greeting) {
    console.log(`${greeting}, ${this.name}`);
  },
};

const other = { name: "Sita" };

person.greet.call(other, "Hello");   // Hello, Sita
person.greet.apply(other, ["Hi"]);   // Hi, Sita

const greetSita = person.greet.bind(other);
greetSita("Namaste");                // Namaste, Sita

Constructor functions

Before classes, developers used constructor functions with new to create many similar objects — like a blueprint for students or products.

Real-life example: A cookie cutter (constructor) shapes every dough piece the same way. Each cookie (object) can have different toppings later.

Constructor function
function Student(name, grade) {
  this.name = name;
  this.grade = grade;
  this.study = function () {
    return `${this.name} is studying for grade ${this.grade}`;
  };
}

const asha = new Student("Asha", 10);
const ravi = new Student("Ravi", 11);
console.log(asha.study()); // Asha is studying for grade 10

Prototypes (brief)

Every JavaScript object has a hidden link to a prototype object. Methods shared on the prototype save memory and let all instances use the same function.

Classes use prototypes under the hood. You may see __proto__ or Object.getPrototypeOf in debugging.

Real-life example: A family recipe book (prototype) sits in the kitchen. Every child (object) can cook the same dishes without each one copying the whole book.

Prototype method
function Course(title) {
  this.title = title;
}

Course.prototype.describe = function () {
  return `Course: ${this.title}`;
};

const js = new Course("JavaScript Fundamentals");
console.log(js.describe()); // Course: JavaScript Fundamentals

Object.keys, values, and entries

These helpers turn an object into lists you can loop over easily.

Real-life example: Object.keys is like listing all drawer labels. values is what is inside each drawer. entries gives you label + contents as pairs.

Loop over object data
const profile = { name: "Asha", city: "Delhi", grade: 10 };

Object.keys(profile);    // ["name", "city", "grade"]
Object.values(profile);  // ["Asha", "Delhi", 10]
Object.entries(profile); // [["name","Asha"], ["city","Delhi"], ...]

for (const [key, value] of Object.entries(profile)) {
  console.log(`${key}: ${value}`);
}

Destructuring

Destructuring pulls values out of objects or arrays into short variable names.

Real-life example: Opening a gift box and taking out each item one by one — you name them as you unpack instead of reaching blindly.

Object and array destructuring
const user = { name: "Ravi", age: 15, city: "Mumbai" };
const { name, city } = user;
const { age: userAge } = user; // rename while destructuring

const colors = ["red", "green", "blue"];
const [first, , third] = colors; // skip green

console.log(name, city, userAge, first, third);

Spread clone

The spread operator {...obj} makes a shallow copy. Change the copy without touching the original top-level fields.

Real-life example: Photocopying a form — you write on the copy; the original file in the cabinet stays unchanged.

Clone and update
const original = { title: "HTML Basics", done: false, tags: ["web"] };
const copy = { ...original, done: true };

copy.done;        // true
original.done;    // false — original not changed
copy.tags.push("html"); // nested arrays still shared — deep clone needs extra care

Getters and setters (brief)

Getters and setters let you run code when someone reads or writes a property. Useful for validation and computed values.

Real-life example: A shop scale shows weight (getter) when you place fruit on it. The setter checks the weight is not negative before saving.

Getter and setter
const account = {
  _balance: 100,
  get balance() {
    return `₹${this._balance}`;
  },
  set balance(amount) {
    if (amount < 0) throw new Error("Balance cannot be negative");
    this._balance = amount;
  },
};

account.balance = 250;
console.log(account.balance); // ₹250

Class syntax

The class keyword is modern sugar over prototypes. It groups constructor logic and methods in one clear block.

Real-life example: A class is like a school admission form template — every student fills the same fields, but each student has their own name and roll number.

Basic class
class Lesson {
  constructor(title, duration) {
    this.title = title;
    this.duration = duration;
    this.completed = false;
  }

  complete() {
    this.completed = true;
    return `${this.title} done!`;
  }
}

const intro = new Lesson("JS Intro", "10 min");
intro.complete(); // JS Intro done!

Constructor

The constructor runs when you use new ClassName(). Use it to set up starting values.

Real-life example: When a new phone is turned on for the first time, setup runs once — language, time, account. Constructor is that first-time setup.

Constructor with defaults
class QuizQuestion {
  constructor(text, options, answerIndex = 0) {
    this.text = text;
    this.options = options;
    this.answerIndex = answerIndex;
  }
}

const q1 = new QuizQuestion(
  "What runs in the browser?",
  ["Python", "JavaScript", "C++"],
  1
);

Methods

Methods are functions inside a class. They describe what objects of that class can do.

Real-life example: A car class has methods like startEngine, brake, and honk — actions the car can perform.

Instance methods
class ShoppingCart {
  constructor() {
    this.items = [];
  }

  add(item) {
    this.items.push(item);
  }

  total() {
    return this.items.reduce((sum, i) => sum + i.price, 0);
  }
}

const cart = new ShoppingCart();
cart.add({ name: "Notebook", price: 120 });
cart.add({ name: "Pen", price: 20 });
console.log(cart.total()); // 140

extends and super

extends creates a child class from a parent class. super calls the parent constructor or parent methods.

Real-life example: A ElectricCar extends Car — it has everything a normal car has, plus a battery. super is like saying "do what my parent does first, then add my extra step."

Inheritance
class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    return `${this.name} makes a sound`;
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // call Animal constructor
    this.breed = breed;
  }
  speak() {
    return `${super.speak()} — actually, woof!`;
  }
}

new Dog("Bruno", "Lab").speak();

Static methods (brief)

Static methods belong to the class itself, not to each instance. Use them for helpers that do not need object data.

Real-life example: A school office phone number (static) is the same for every student. You call the school, not each student, for the address.

Static helper
class MathHelper {
  static add(a, b) {
    return a + b;
  }
  static isEven(n) {
    return n % 2 === 0;
  }
}

MathHelper.add(3, 4);     // 7 — no "new" needed
MathHelper.isEven(10);    // true

What is JSON?

JSON (JavaScript Object Notation) is a text format for sending and saving data. It looks like a JavaScript object but is always a string when traveling over the network.

Real-life example: JSON is like a packed lunch box with labels — name, rice, curry — written in a standard format every school understands.

  • Keys must be in double quotes.
  • Values can be string, number, boolean, null, array, or object.
  • No functions, comments, or trailing commas in strict JSON.

JSON.stringify

JSON.stringify turns a JavaScript value into a JSON string. Send it to a server or save it in localStorage.

Real-life example: Packing clothes into a suitcase (string) before a flight — you cannot wear them on the plane until you unpack at the hotel.

Object to JSON string
const user = { name: "Asha", grade: 10, active: true };
const jsonText = JSON.stringify(user);
console.log(jsonText);
// {"name":"Asha","grade":10,"active":true}

JSON.stringify(user, null, 2); // pretty print with 2-space indent

JSON.parse

JSON.parse turns a JSON string back into a JavaScript object or array.

Real-life example: Opening the suitcase at the hotel — string becomes usable clothes (object) again.

JSON string to object
const text = '{"course":"JavaScript","lesson":19}';
const data = JSON.parse(text);
console.log(data.course); // JavaScript

try {
  JSON.parse("{ bad json }");
} catch (e) {
  console.error("Invalid JSON:", e.message);
}

Common API payload shape

Most APIs return JSON with a predictable shape: a success flag, a data field, and sometimes an error message.

Real-life example: A pizza delivery app reply — status: "on the way", data: { orderId, eta }, error: null. Same pattern every time makes coding easier.

Typical API response
// What many REST APIs return
const apiResponse = {
  success: true,
  data: {
    courses: [
      { id: 1, title: "HTML & CSS", slug: "html-css-zero-to-hero" },
      { id: 2, title: "JavaScript", slug: "javascript-fundamentals" },
    ],
  },
  error: null,
};

const courses = apiResponse.data.courses;

JSON vs JavaScript object

A JS object can hold functions, undefined, and symbols. JSON is stricter — text only, for sharing between systems.

Real-life example: A JS object is your full diary with doodles and phone numbers. JSON is the typed page you email — only plain facts, no secrets scribbled in margins.

Valid in JS, invalid in JSON
const jsObject = {
  name: "Ravi",
  greet() { return "Hi"; },  // functions — OK in JS, NOT in JSON
  extra: undefined,         // undefined — OK in JS, NOT in JSON
};

// JSON.stringify skips functions and undefined keys
JSON.stringify(jsObject); // {"name":"Ravi"}

The callback problem

Old async code used nested callbacks. Many callbacks inside callbacks create "callback hell" — hard to read and debug.

Real-life example: Calling a friend who calls another friend who calls a third person just to ask one question — too many steps in a chain.

Nested callbacks (hard to read)
getUser(1, (user) => {
  getCourses(user.id, (courses) => {
    getLesson(courses[0].id, (lesson) => {
      console.log(lesson.title); // deeply nested
    });
  });
});
// Promises and async/await fix this style

Promises

A Promise represents work that will finish later — success (resolve) or failure (reject). Chain .then and .catch instead of nesting.

Real-life example: A food delivery promise — "We will bring pizza in 30 minutes or give your money back." You wait without blocking the door.

Promise chain
function wait(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

wait(1000)
  .then(() => fetch("https://jsonplaceholder.typicode.com/posts/1"))
  .then((res) => res.json())
  .then((post) => console.log(post.title))
  .catch((err) => console.error(err));

async and await

async marks a function that returns a Promise. await pauses inside that function until a Promise finishes — code looks straight, like sync code.

Real-life example: await is like waiting at the counter for your coffee order number to be called — you do other things on your phone, but your turn comes in order.

async/await
async function loadPost() {
  const res = await fetch("https://jsonplaceholder.typicode.com/posts/1");
  const post = await res.json();
  return post.title;
}

loadPost().then(console.log);

fetch example

fetch is the modern way to get data from URLs in the browser. It returns a Promise.

Real-life example: fetch is like sending a waiter to the kitchen (server) to bring your dish (JSON data) back to your table (browser).

GET request with fetch
async function getCourses() {
  const response = await fetch("/api/courses");
  if (!response.ok) {
    throw new Error("Network error: " + response.status);
  }
  return response.json();
}

Error handling

Always wrap async code in try/catch. Network fails, servers return errors, and JSON can be invalid.

Real-life example: Ordering online — if payment fails, you see an error message instead of a blank screen. Good apps always plan for failure.

try/catch with async
async function safeLoad() {
  try {
    const res = await fetch("/api/data");
    if (!res.ok) throw new Error("HTTP " + res.status);
    return await res.json();
  } catch (error) {
    console.error("Could not load:", error.message);
    return { courses: [] }; // fallback
  }
}

Event loop — how async works

JavaScript runs one task at a time on the call stack. Slow jobs (timers, fetch) go to Web APIs. When done, callbacks join a queue and return to the stack.

Real-life example: A single cashier (call stack) serves one customer. While pizza bakes (Web API), others wait in line (queue) — the shop never freezes.

JavaScript event loop

Why modules matter

Modules split code into separate files. Each file can export what others need and hide private details. Big apps stay organized.

Real-life example: A school has separate departments — math, science, sports. Each department shares only what others need; internal notes stay private.

  • One file = one responsibility (utils, api, components).
  • Avoid global variables polluting window.
  • Use type="module" in script tags or bundlers like Vite.

Named export and import

Named exports let you share many values from one file. Import them with curly braces and matching names.

Real-life example: A toolbox with labeled tools — export hammer, export screwdriver. You pick only the tools you need for today's job.

Named exports
// math.js
export function add(a, b) { return a + b; }
export function subtract(a, b) { return a - b; }

// app.js
import { add, subtract } from "./math.js";
console.log(add(5, 3)); // 8

Default export and import

Each file can have one default export — the main thing that file provides. Import it with any name you choose.

Real-life example: A book's main author (default export) is on the cover. Supporting writers (named exports) are listed inside.

Default export
// greet.js
export default function greet(name) {
  return `Welcome to Rishtaara, ${name}!`;
}

// main.js
import greet from "./greet.js";
console.log(greet("Asha"));

Using modules in HTML

Add type="module" to your script tag. The browser loads imports automatically. File paths need .js and often start with ./ for local files.

Real-life example: Module script is like a main chapter that says "also read page 5 and page 9" — the browser fetches those pages in order.

Module script in HTML
<script type="module" src="./main.js"></script>
<!-- main.js can import from ./utils.js -->

Proxy — get and set traps

Proxy wraps an object and lets you run code when someone reads or writes a property. Simple use: logging, validation, or default values.

Real-life example: A security guard at a building door (Proxy) checks every visitor (get/set) before they enter or leave a room (target object).

Proxy with get and set traps
const user = { name: "Asha", score: 0 };

const tracked = new Proxy(user, {
  get(target, key) {
    console.log("Reading:", key);
    return target[key];
  },
  set(target, key, value) {
    if (key === "score" && value < 0) {
      throw new Error("Score cannot be negative");
    }
    target[key] = value;
    return true;
  },
});

tracked.score = 10;
console.log(tracked.name);

ArrayBuffer — raw binary memory

ArrayBuffer holds raw bytes in memory. You cannot read it directly — you view it through typed arrays.

Real-life example: ArrayBuffer is like an empty warehouse floor. Typed arrays are labeled shelves (8-bit, 16-bit) that tell you how to read each box.

Create ArrayBuffer
// 16 bytes of raw memory
const buffer = new ArrayBuffer(16);
console.log(buffer.byteLength); // 16

Uint8Array — when to use typed arrays

Typed arrays like Uint8Array read/write numbers in a fixed format. Use them for images, audio, files, WebGL, and network binary data.

Real-life example: A digital photo is millions of byte values for red, green, blue. Uint8Array lets JavaScript work with that raw pixel data quickly.

Uint8Array example
const buffer = new ArrayBuffer(4);
const bytes = new Uint8Array(buffer);

bytes[0] = 255;
bytes[1] = 128;
bytes[2] = 64;
bytes[3] = 0;

console.log(bytes); // Uint8Array [255, 128, 64, 0]

Parent, children, and siblings

Every element in the DOM is connected like a family tree. Move up to parentElement, down through children, or sideways to nextElementSibling.

Real-life example: In a family photo, you can look at your parent above you, kids below you, or brother/sister beside you — same idea in the DOM tree.

Traverse the DOM
const card = document.querySelector(".lesson-card");

card.parentElement;           // wrapper div
card.children;                // HTMLCollection of child nodes
card.firstElementChild;       // first child element
card.nextElementSibling;      // next card beside it
card.previousElementSibling;  // previous card

querySelectorAll

querySelectorAll returns a NodeList of all elements matching a CSS selector. Loop with forEach or convert to an array.

Real-life example: Finding every student wearing a blue uniform in a school photo — one search, many matches.

Select many elements
const buttons = document.querySelectorAll(".course-list button");

buttons.forEach((btn, index) => {
  btn.textContent = `Lesson ${index + 1}`;
});

// Change all paragraph colors
document.querySelectorAll("main p").forEach((p) => {
  p.style.color = "#334155";
});

closest

closest starts from an element and walks up the tree until it finds a match. Great for event delegation on nested clicks.

Real-life example: You touch a leaf on a tree; closest walks up the branch to find the whole tree trunk (parent card or list item).

Find ancestor with closest
document.querySelector(".course-list").addEventListener("click", (e) => {
  const item = e.target.closest("li");
  if (!item) return;
  console.log("Clicked lesson:", item.dataset.lessonId);
});

dataset — data attributes

HTML data-* attributes store extra info on elements. In JS, use element.dataset — camelCase names (data-lesson-id becomes dataset.lessonId).

Real-life example: Sticky notes on folders — data-course="js" on the HTML tag is a label JavaScript reads without showing it on screen.

Read and write data attributes
<button data-lesson-id="16" data-done="false">Start lesson</button>
JavaScript dataset
const btn = document.querySelector("button");
console.log(btn.dataset.lessonId); // "16"
btn.dataset.done = "true";         // updates data-done attribute

window — the browser global

In the browser, window is the global object. alert, setTimeout, fetch, and document all live on window.

Real-life example: window is like the whole classroom — everything you can use without asking permission is already in the room.

window properties
console.log(window.innerWidth, window.innerHeight);
window.open("https://rishtaara.com", "_blank"); // open new tab
// document === window.document

navigator and location

navigator tells you about the browser and device. location holds the current URL — change it to navigate or read query params.

Real-life example: navigator is your phone's settings screen (language, online/offline). location is the address bar showing where you are on the map.

navigator and location
navigator.language;       // e.g. "en-IN"
navigator.onLine;         // true if connected

location.href;            // full URL
location.pathname;        // /learn/javascript
location.search;          // ?tab=lessons
history.back();           // go to previous page

localStorage and sessionStorage

Both store key-value strings in the browser. localStorage stays until cleared. sessionStorage clears when the tab closes.

Real-life example: localStorage is a school locker — your stuff stays all year. sessionStorage is a desk drawer — emptied when class ends (tab closes).

Save and load data
localStorage.setItem("theme", "dark");
localStorage.getItem("theme"); // "dark"

sessionStorage.setItem("quizStep", "3");

// Store objects — always stringify
localStorage.setItem("progress", JSON.stringify({ lesson: 20, done: true }));
const progress = JSON.parse(localStorage.getItem("progress") || "{}");

fetch — HTTP from the browser

fetch talks to servers over HTTP. You used it in async lessons — here it sits with other browser APIs that go beyond core JavaScript language.

Real-life example: fetch is the post office of your browser — send letters (requests), receive packages (JSON responses).

POST JSON to an API
async function saveScore(name, score) {
  const res = await fetch("/api/scores", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ name, score }),
  });
  return res.json();
}

Geolocation (brief)

navigator.geolocation gets the user's location with permission. Used for maps, nearby shops, and weather.

Real-life example: Your phone asks "Allow location?" so Uber knows where to pick you up — same idea in the browser.

Get current position
navigator.geolocation.getCurrentPosition(
  (pos) => {
    console.log(pos.coords.latitude, pos.coords.longitude);
  },
  (err) => console.error("Location denied:", err.message)
);

Notification API (brief)

The Notification API shows desktop alerts if the user allows. Useful for reminders — "Your lesson is ready!"

Real-life example: A doorbell notification on your phone — you opted in, and now the app can ping you even when the tab is in the background.

Request permission and notify
async function notifyUser() {
  if (Notification.permission === "default") {
    await Notification.requestPermission();
  }
  if (Notification.permission === "granted") {
    new Notification("Rishtaara", { body: "Time for your JS lesson!" });
  }
}

Canvas 2D — simple drawing

The <canvas> element is a blank bitmap. JavaScript draws shapes, text, and images with the 2D context API.

Real-life example: Canvas is like a whiteboard. getContext("2d") is your marker — you draw lines, circles, and text pixel by pixel.

Draw on canvas
<canvas id="board" width="300" height="150"></canvas>
Canvas 2D JavaScript
const canvas = document.querySelector("#board");
const ctx = canvas.getContext("2d");

ctx.fillStyle = "#0891b2";
ctx.fillRect(10, 10, 120, 60);

ctx.strokeStyle = "#334155";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.arc(200, 75, 40, 0, Math.PI * 2);
ctx.stroke();

ctx.fillStyle = "#0f172a";
ctx.font = "16px sans-serif";
ctx.fillText("Hello Rishtaara!", 10, 130);

SVG and JavaScript

SVG is vector graphics in HTML — shapes stay sharp when zoomed. JavaScript can change SVG with querySelector, setAttribute, and classList, just like HTML.

Real-life example: Canvas is a painted mural (pixels). SVG is a cut-out paper diagram — you can resize it cleanly and move each piece with JS.

Change SVG with JS
<svg width="100" height="100">
  <circle id="dot" cx="50" cy="50" r="20" fill="orange" />
</svg>
Animate SVG fill
const dot = document.querySelector("#dot");
dot.setAttribute("fill", "#0891b2");
dot.setAttribute("r", "30");

AJAX — XMLHttpRequest vs fetch

AJAX means loading data without reloading the whole page. XMLHttpRequest was the old tool; fetch is the modern replacement.

Real-life example: Old AJAX is like sending a letter and waiting weeks. fetch is like instant chat — same goal, faster and simpler today.

Historical note: AJAX changed the web in the 2000s. New projects should use fetch or axios, not XMLHttpRequest.
Legacy XMLHttpRequest (historical)
// OLD way — you may see this in legacy code
const xhr = new XMLHttpRequest();
xhr.open("GET", "/api/courses");
xhr.onload = () => console.log(JSON.parse(xhr.responseText));
xhr.send();

// MODERN way — use fetch instead
fetch("/api/courses").then((r) => r.json()).then(console.log);

jQuery — what it was and why less needed now

jQuery (circa 2006) made DOM and AJAX easy when browsers behaved differently. Modern browsers are consistent — vanilla JS and frameworks replaced most jQuery.

Real-life example: jQuery was like a universal remote when every TV had different buttons. Today TVs (browsers) share one standard remote (modern JS).

Classic jQuery $ example
// Legacy jQuery — still on some old sites
$("#submit-btn").click(function () {
  $(".message").text("Saved!").fadeIn();
});

// Same idea in modern vanilla JS
document.querySelector("#submit-btn").addEventListener("click", () => {
  const msg = document.querySelector(".message");
  msg.textContent = "Saved!";
  msg.style.opacity = "1";
});

JSONP — obsolete vs CORS

JSONP was a hack to load data from another domain before CORS existed. It wrapped JSON in a script tag callback. CORS and fetch made JSONP obsolete.

Real-life example: JSONP was shouting your order through a fence because the gate was locked. CORS is the gatekeeper who checks ID and lets safe requests through.

  • JSONP — legacy cross-domain trick; security risks; avoid in new code.
  • CORS — server sends headers like Access-Control-Allow-Origin.
  • Modern APIs use fetch with proper CORS — no script-tag hacks.
You may read about JSONP in old tutorials. Understand it for interviews and maintenance — do not use it in new projects.

Form validation

Check user input before submit — empty fields, email format, minimum length. Show errors next to fields.

Real-life example: A bouncer at a club checks ID before entry — form validation checks data before it goes to the server.

Simple form validation
document.querySelector("#signup-form").addEventListener("submit", (e) => {
  e.preventDefault();
  const email = document.querySelector("#email").value.trim();
  const error = document.querySelector("#email-error");

  if (!email.includes("@")) {
    error.textContent = "Please enter a valid email.";
    return;
  }
  error.textContent = "";
  alert("Form OK — ready to send!");
});

Toggle menu (mobile nav)

A hamburger button adds or removes a class on the nav to show or hide links on small screens.

Real-life example: A folding map — tap to open full view, tap again to fold it back into your pocket.

Toggle navigation
const menuBtn = document.querySelector("#menu-btn");
const nav = document.querySelector("#main-nav");

menuBtn.addEventListener("click", () => {
  nav.classList.toggle("open");
  menuBtn.setAttribute(
    "aria-expanded",
    nav.classList.contains("open")
  );
});

Counter

Track a number with + and − buttons. Update the screen with textContent each click.

Real-life example: A cricket scoreboard — each run adds one; the display always shows the latest total.

Increment / decrement counter
let count = 0;
const display = document.querySelector("#count");
document.querySelector("#plus").addEventListener("click", () => {
  count++;
  display.textContent = count;
});
document.querySelector("#minus").addEventListener("click", () => {
  count--;
  display.textContent = count;
});

Accordion idea

Only one panel open at a time — click a heading to show its content and hide others.

Real-life example: FAQ on a help page — open one question's answer; closing others keeps the page tidy.

Simple accordion
document.querySelectorAll(".accordion-btn").forEach((btn) => {
  btn.addEventListener("click", () => {
    const panel = btn.nextElementSibling;
    const isOpen = panel.classList.contains("open");

    document.querySelectorAll(".accordion-panel").forEach((p) => {
      p.classList.remove("open");
    });

    if (!isOpen) panel.classList.add("open");
  });
});

What you will build

A full quiz app in one HTML file — questions about learning on Rishtaara, score tracking, next button, and final results screen.

Copy everything below into one file, save as quiz.html, and open in your browser.

Real-life example: This project is like a mini game show in your browser — you host, ask questions, count points, and announce the winner at the end.

Complete Quiz App — HTML + CSS + JS

Paste this entire block. Change questions to make your own quiz for friends or school.

Real-life example: Sharing this file with classmates is like passing a board game — everyone can play the same quiz on any laptop.

quiz.html — full copy-paste project
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Rishtaara Learning Quiz</title>
  <style>
    * { box-sizing: border-box; }
    body {
      font-family: system-ui, sans-serif;
      background: linear-gradient(135deg, #ecfeff, #f0fdf4);
      min-height: 100vh;
      margin: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 1rem;
    }
    .quiz {
      background: #fff;
      border-radius: 16px;
      box-shadow: 0 10px 40px rgba(0,0,0,0.08);
      max-width: 480px;
      width: 100%;
      padding: 1.5rem;
    }
    h1 { color: #0891b2; font-size: 1.4rem; margin-top: 0; }
    .progress { color: #64748b; font-size: 0.9rem; margin-bottom: 1rem; }
    .question { font-size: 1.1rem; font-weight: 600; margin-bottom: 1rem; }
    .options { display: flex; flex-direction: column; gap: 0.5rem; }
    .option {
      padding: 0.75rem 1rem;
      border: 2px solid #e2e8f0;
      border-radius: 10px;
      background: #f8fafc;
      cursor: pointer;
      text-align: left;
      font-size: 1rem;
      transition: border-color 0.2s, background 0.2s;
    }
    .option:hover { border-color: #0891b2; background: #ecfeff; }
    .option.selected { border-color: #0891b2; background: #cffafe; }
    .option.correct { border-color: #16a34a; background: #dcfce7; }
    .option.wrong { border-color: #dc2626; background: #fee2e2; }
    .actions { margin-top: 1.25rem; display: flex; gap: 0.5rem; }
    button {
      flex: 1;
      padding: 0.75rem;
      border: none;
      border-radius: 10px;
      font-size: 1rem;
      cursor: pointer;
    }
    #next-btn { background: #0891b2; color: #fff; }
    #next-btn:disabled { opacity: 0.5; cursor: not-allowed; }
    #restart-btn { background: #e2e8f0; color: #334155; display: none; }
    .result { text-align: center; display: none; }
    .result.show { display: block; }
    .score-big { font-size: 2.5rem; font-weight: 700; color: #0891b2; }
    .hidden { display: none; }
  </style>
</head>
<body>
  <div class="quiz">
    <div id="quiz-screen">
      <h1>Rishtaara Learning Quiz</h1>
      <p class="progress" id="progress">Question 1 of 4</p>
      <p class="question" id="question"></p>
      <div class="options" id="options"></div>
      <div class="actions">
        <button type="button" id="next-btn" disabled>Next</button>
        <button type="button" id="restart-btn">Play again</button>
      </div>
    </div>
    <div class="result" id="result-screen">
      <h1>Well done!</h1>
      <p class="score-big" id="final-score">0/4</p>
      <p id="result-message">Keep learning on Rishtaara.</p>
      <button type="button" id="result-restart">Try again</button>
    </div>
  </div>

  <script>
    const questions = [
      {
        q: "Which language makes web pages interactive?",
        options: ["HTML", "CSS", "JavaScript", "JSON"],
        answer: 2,
      },
      {
        q: "Which keyword declares a constant in modern JS?",
        options: ["var", "let", "const", "static"],
        answer: 2,
      },
      {
        q: "What does JSON.parse do?",
        options: [
          "Turns object to string",
          "Turns JSON string to object",
          "Saves to localStorage",
          "Fetches from API",
        ],
        answer: 1,
      },
      {
        q: "What is the best way to select one element in modern JS?",
        options: [
          "getElementByTag",
          "querySelector",
          "getAll",
          "findElement",
        ],
        answer: 1,
      },
    ];

    let current = 0;
    let score = 0;
    let selected = null;
    let answered = false;

    const progressEl = document.querySelector("#progress");
    const questionEl = document.querySelector("#question");
    const optionsEl = document.querySelector("#options");
    const nextBtn = document.querySelector("#next-btn");
    const restartBtn = document.querySelector("#restart-btn");
    const quizScreen = document.querySelector("#quiz-screen");
    const resultScreen = document.querySelector("#result-screen");
    const finalScoreEl = document.querySelector("#final-score");
    const resultMessageEl = document.querySelector("#result-message");

    function renderQuestion() {
      answered = false;
      selected = null;
      nextBtn.disabled = true;
      nextBtn.textContent = current === questions.length - 1 ? "Finish" : "Next";
      restartBtn.style.display = "none";

      const q = questions[current];
      progressEl.textContent = `Question ${current + 1} of ${questions.length}`;
      questionEl.textContent = q.q;
      optionsEl.innerHTML = "";

      q.options.forEach((text, index) => {
        const btn = document.createElement("button");
        btn.type = "button";
        btn.className = "option";
        btn.textContent = text;
        btn.addEventListener("click", () => selectOption(index, btn));
        optionsEl.appendChild(btn);
      });
    }

    function selectOption(index, btn) {
      if (answered) return;
      selected = index;
      document.querySelectorAll(".option").forEach((o) => o.classList.remove("selected"));
      btn.classList.add("selected");
      nextBtn.disabled = false;
    }

    function showAnswerColors() {
      const q = questions[current];
      const buttons = document.querySelectorAll(".option");
      buttons.forEach((btn, i) => {
        if (i === q.answer) btn.classList.add("correct");
        else if (i === selected) btn.classList.add("wrong");
      });
    }

    function nextQuestion() {
      if (selected === null) return;

      if (!answered) {
        if (selected === questions[current].answer) score++;
        answered = true;
        showAnswerColors();
        nextBtn.textContent = current === questions.length - 1 ? "See results" : "Next";
        return;
      }

      current++;
      if (current >= questions.length) {
        showResults();
      } else {
        renderQuestion();
      }
    }

    function showResults() {
      quizScreen.classList.add("hidden");
      resultScreen.classList.add("show");
      finalScoreEl.textContent = `${score}/${questions.length}`;
      const pct = (score / questions.length) * 100;
      resultMessageEl.textContent =
        pct === 100
          ? "Perfect score! You are ready for React."
          : pct >= 75
            ? "Great job! Review missed topics and try again."
            : "Keep practicing — Rishtaara courses are here for you.";
    }

    function restart() {
      current = 0;
      score = 0;
      quizScreen.classList.remove("hidden");
      resultScreen.classList.remove("show");
      renderQuestion();
    }

    nextBtn.addEventListener("click", nextQuestion);
    restartBtn.addEventListener("click", restart);
    document.querySelector("#result-restart").addEventListener("click", restart);

    renderQuestion();
  </script>
</body>
</html>

How the quiz works

Questions live in an array. renderQuestion builds buttons. selectOption tracks your pick. nextQuestion checks the answer, colors correct/wrong, then moves on.

Real-life example: The quiz is a vending machine — you pick a snack (answer), the machine checks stock (correct key), then serves the next item or your receipt (final score).

  • Add more objects to the questions array to grow the quiz.
  • Save high scores with localStorage for a bonus challenge.
  • Style with your own colors — practice CSS from the HTML & CSS course.

What's next

You finished the JavaScript advanced track. Keep building — frameworks make bigger apps easier.

Real-life example: Vanilla JS is like learning to walk. React is like getting a bicycle — same destination, faster on long journeys.

  • React course: /learn/web-development/react-complete-guide
  • MCQ practice: /mcq/javascript-mcq
  • Interview prep: /interview/javascript-interview

Key Takeaways

  • JavaScript makes pages interactive — start with syntax, then DOM, then async.
  • Prefer const, then let; avoid var in modern code.
  • Functions, arrays, and objects are the everyday tools of JS apps.
  • Promises and async/await replace callback hell for network and timers.
  • The DOM connects JS to HTML — query elements, listen to events, update the page.
  • JSON is the common data format for APIs; parse and stringify carefully.
  • Modules keep code organized; learn export/import early.
  • Old tools (AJAX XHR, jQuery, JSONP) are useful history — prefer fetch and modern JS.
  • Practice with small projects: quiz, todo, form validation.

Frequently Asked Questions

HTML/CSS ke baad JavaScript kyun?
HTML is structure, CSS is look, JavaScript is behavior. Without JS, buttons and forms cannot react intelligently in the browser.
var, let, const mein se kya use karun?
Use const by default. Use let when the value must change. Avoid var — it has confusing function scope and hoisting.
== ya ===?
Always prefer === (strict equality). It does not convert types. == can surprise you (e.g. 0 == "" is true).
Promise aur async/await mein farak?
Both handle async work. async/await is clearer syntax on top of Promises. await pauses inside an async function until the Promise settles.
jQuery ab seekhna chahiye?
Not required for beginners. Modern browsers + vanilla JS (querySelector, fetch, classList) cover what jQuery used to solve. Learn it only if a job or old codebase needs it.