Every JavaScript concept in one page โ variables to async/await, DOM to closures. Each section links to a deeper lesson where available.
const name = "Priya"; // can't be reassigned โ your DEFAULT let score = 10; // reassignable, block-scoped var old = 1; // legacy โ function-scoped, hoisted. Avoid. // 7 primitives + object: "text" 42 true undefined null Symbol() 10n // BigInt { } [ ] function(){} // all objects typeof "a" // "string" typeof null // "object" โ famous historical bug, asked in interviews
Deeper lesson: Variables
5 + 3, 10 % 3, 2 ** 8 // arithmetic (% = remainder, ** = power) x += 1; x++; // shorthand 5 == "5" // true โ loose, converts types. AVOID 5 === "5" // false โ strict, checks type too. ALWAYS USE && || ! // logical age >= 18 ? "adult" : "minor" // ternary user ?? "guest" // nullish โ fallback only for null/undefined user?.address?.city // optional chaining โ no crash if missing
Deeper lesson: Operators
if (marks >= 90) grade = "O"; else if (marks >= 80) grade = "A+"; else grade = "B"; switch (day) { case "sat": case "sun": type = "weekend"; break; default: type = "weekday"; } // falsy values โ memorize: false, 0, "", null, undefined, NaN if (items.length) { โฆ } // truthy check
Deeper lesson: Conditionals
for (let i = 0; i < 5; i++) { โฆ } // classic โ when you need the index for (const item of array) { โฆ } // values โ your default for arrays for (const key in object) { โฆ } // object keys while (condition) { โฆ } do { โฆ } while (condition); // runs at least once break; // exit the loop continue; // skip to next iteration array.forEach((item, i) => { โฆ }); // callback style โ no break allowed
Deeper lesson: Loops
const s = "Anna University"; s.length // 15 s.toUpperCase() s.toLowerCase() s.includes("Univ") // true s.startsWith("Anna") s.endsWith("ity") s.indexOf("U") // 5 (-1 if not found) s.slice(0, 4) // "Anna" (end not included) s.replace("Anna", "Madras") s.replaceAll("a", "@") s.trim() // remove surrounding whitespace s.split(" ") // ["Anna", "University"] s.charAt(0) s[0] // "A" s.padStart(20, "*") s.repeat(2) // template literals โ modern string building const msg = `Hello ${name}, you scored ${marks * 2}`;
Number("42") parseInt("42px") parseFloat("3.14") (9.4567).toFixed(2) // "9.46" โ string! wrap with + to get number Number.isInteger(5) isNaN("abc") Math.round(4.5) Math.floor(4.9) Math.ceil(4.1) Math.abs(-5) Math.max(1, 5, 3) Math.min(...arr) Math.sqrt(16) Math.pow(2, 10) Math.random() // 0 to <1 Math.floor(Math.random() * 6) + 1 // dice: 1โ6 0.1 + 0.2 === 0.3 // false! floating point โ interview classic. // fix: Math.abs(a-b) < Number.EPSILON
function add(a, b = 10) { return a + b; } // declaration (hoisted) + default param const add = function(a, b) { return a + b; }; // expression const add = (a, b) => a + b; // arrow โ implicit return const square = n => n * n; // single param, no parens function sum(...nums) { // rest โ any number of args return nums.reduce((t, n) => t + n, 0); } // callbacks โ functions passed to functions [3,1,2].sort((a, b) => a - b); // IIFE โ runs immediately (() => { console.log("init"); })();
Arrow vs regular โ the interview answer: arrows have no own this (they inherit it), no arguments, and can't be constructors. Use arrows for callbacks; regular functions for object methods.
Deeper lessons: Functions ยท Arrow Functions
const a = [1, 2, 3]; a.push(4) a.pop() a.unshift(0) a.shift() // end/start add & remove a.slice(1, 3) // copy portion โ does NOT mutate a.splice(1, 2) // remove/insert in place โ DOES mutate a.indexOf(2) a.includes(3) a.join("-") a.reverse() a.flat() // THE interview trio: const doubled = a.map(n => n * 2); // transform each โ new array const evens = a.filter(n => n % 2 === 0); // keep matching โ new array const total = a.reduce((sum, n) => sum + n, 0); // fold into one value a.find(n => n > 1) // first match (value) a.findIndex(n => n > 1) // first match (index) a.some(n => n > 2) // at least one passes? a.every(n => n > 0) // all pass? a.sort((x, y) => x - y) // numeric sort โ without comparator it sorts as strings! [...a] // spread โ shallow copy Array.from({length: 5}, (_, i) => i) // [0,1,2,3,4]
Deeper lessons: Arrays ยท Array Methods
const student = { name: "Priya", cgpa: 8.9, greet() { return `Hi, I'm ${this.name}`; } }; student.name student["cgpa"] // access student.dept = "CSE"; delete student.cgpa; // add / remove Object.keys(student) // ["name", "greet", "dept"] Object.values(student) Object.entries(student) { ...student, year: 4 } // clone + extend (shallow) Object.freeze(student) // make immutable // destructuring const { name, dept = "IT" } = student; const [first, ...rest] = [1, 2, 3];
Deeper lessons: Objects ยท Destructuring
let/const, template literals, arrow functions, default params โ covered above[...a, ...b], {...obj}, function f(...args) โ lessonnew Map() (any-type keys, ordered), new Set([1,1,2]) โ unique values โ [...new Set(arr)] is the classic dedupe tricka?.b, nullish coalescing a ?? fallback// select const el = document.querySelector(".card"); // first match โ CSS selector const all = document.querySelectorAll("li"); // NodeList โ loop with forEach const byId = document.getElementById("app"); // change el.textContent = "Safe text"; // text only โ XSS-safe el.innerHTML = "<b>HTML</b>"; // parses HTML โ never with user input el.style.color = "tomato"; el.classList.add("active") .remove() .toggle() .contains() el.setAttribute("href", "/") el.dataset.userId // data-user-id // create & insert const li = document.createElement("li"); li.textContent = "New item"; list.appendChild(li); list.prepend(li); el.remove(); el.insertAdjacentHTML("beforeend", "<span>hi</span>");
Deeper lessons: DOM Intro ยท Selecting ยท Manipulating
btn.addEventListener("click", (e) => { e.preventDefault(); // stop form submit / link navigation e.stopPropagation(); // stop bubbling to parents console.log(e.target); // element that was clicked }); // common events: click dblclick input change submit keydown // mouseover focus blur scroll load DOMContentLoaded input.addEventListener("keydown", e => { if (e.key === "Enter") send(); }); // EVENT DELEGATION โ one listener for many children (interview favourite) list.addEventListener("click", e => { if (e.target.matches("li")) e.target.classList.toggle("done"); }); // works for items added later + uses less memory
Deeper lesson: Events
// SCOPE: where a variable is visible โ global, function, block {} // let/const are block-scoped; var is function-scoped // HOISTING: declarations move to the top before execution console.log(x); var x = 5; // undefined (declared, not assigned) console.log(y); let y = 5; // ReferenceError โ "temporal dead zone" // CLOSURE: a function remembers variables from where it was CREATED function counter() { let count = 0; // private โ nothing outside can touch it return () => ++count; } const inc = counter(); inc(); inc(); // 1, 2 โ count lives on inside the closure
Closures power private state, event handlers, and React hooks โ the single most-asked JS interview concept. Deeper lesson: Scope
this & Classes// `this` = whoever CALLS the function const user = { name: "Ravi", hi() { return this.name; } // user.hi() โ "Ravi" }; // control it manually: fn.call(obj), fn.apply(obj, args), fn.bind(obj) class Student { #marks = 0; // private field constructor(name) { this.name = name; } greet() { return `Hi ${this.name}`; } static school() { return "Anna University"; } get grade() { return this.#marks > 90 ? "O" : "A"; } } class Topper extends Student { constructor(name) { super(name); } }
// A Promise = a future value: pending โ fulfilled or rejected const p = new Promise((resolve, reject) => { setTimeout(() => resolve("done"), 1000); }); p.then(v => console.log(v)).catch(err => โฆ).finally(() => โฆ); // async/await โ same thing, reads like normal code async function load() { try { const data = await fetchData(); // pauses HERE, not the browser console.log(data); } catch (err) { console.error(err); } } Promise.all([p1, p2, p3]) // parallel โ fails if ANY fails Promise.allSettled([p1, p2]) // parallel โ never fails, gives statuses Promise.race([p1, timeout]) // first to finish wins
Event loop (interview): JS is single-threaded. Sync code runs first, then microtasks (promise callbacks), then macrotasks (setTimeout). So Promise.then always beats setTimeout(fn, 0).
Deeper lessons: Promises ยท async/await
// GET const res = await fetch("https://api.example.com/users"); if (!res.ok) throw new Error(res.status); // fetch does NOT reject on 404! const data = await res.json(); // POST await fetch("/api/users", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: "Priya", dept: "CSE" }) }); // JSON โ text โ object JSON.stringify(obj) // object โ string (for storage/sending) JSON.parse('{"a":1}') // string โ object JSON.stringify(obj, null, 2) // pretty-printed
Deeper lesson: Fetch API
localStorage.setItem("theme", "dark"); // persists forever (~5MB) localStorage.getItem("theme"); // "dark" (or null) localStorage.removeItem("theme"); localStorage.clear(); // objects must be stringified: localStorage.setItem("user", JSON.stringify({ name: "Ravi" })); const user = JSON.parse(localStorage.getItem("user") ?? "{}"); // sessionStorage: same API, cleared when the tab closes
Our DSA judge saves your solved problems and code drafts exactly this way.
try { const data = JSON.parse(badInput); } catch (err) { console.error(err.name, err.message); // SyntaxError, ... } finally { spinner.hide(); // always runs } throw new Error("Invalid marks"); // raise your own class ValidationError extends Error { // custom error types constructor(msg) { super(msg); this.name = "ValidationError"; } }
const id = setTimeout(() => console.log("once, after 1s"), 1000); clearTimeout(id); const tick = setInterval(() => console.log("every second"), 1000); clearInterval(tick); // DEBOUNCE โ run only after the user stops typing (search boxes) let t; input.addEventListener("input", () => { clearTimeout(t); t = setTimeout(() => search(input.value), 400); });
// utils.js export const PI = 3.14159; export function area(r) { return PI * r * r; } export default class Circle { โฆ } // main.js import Circle, { PI, area } from "./utils.js"; import * as utils from "./utils.js"; // in HTML: type="module" enables imports + defer + strict mode <script type="module" src="main.js"></script>
const re = /^[a-z0-9._]+@[a-z]+\.[a-z]{2,}$/i; // simple email shape re.test("hi@site.com") // true "a1b2".match(/\d/g) // ["1","2"] "2026-07-02".replace(/-/g, "/") // "2026/07/02" // cheat: \d digit \w word-char \s space . any + one-or-more // * zero-or-more ? optional ^ start $ end [abc] set {2,4} count
const by default, let when reassigning, never var=== always; handle falsy values deliberatelytextContent for user data โ innerHTML invites XSSres.ok after every fetchNow prove it: build in the Code Playground, solve the 24 DSA problems, and drill the 100 JavaScript interview questions.