👑 Premium Sign in Sign up

Language lab · Beginner → Web

🟨 JavaScript

Concept → trace → write code → run tests → explain why → improve → mini-project. Start in the browser if you like; set up your own computer when you are ready.

🧪 Runs in your browserOfficial download & docs ↗

📖 Topics with real code (16)

Every verified output below was produced by running the code with v22.23.4 on 5 Nov 2026. Open a topic to edit the code and run it right here in your browser.

🌱 Beginner (5)

Variables and data types

let can change, const cannot be reassigned. JavaScript types: number (int and decimal together), boolean, string, null, undefined, bigint and object. typeof shows the type.

let age = 15;
const height = 1.62;
const isStudent = true;
const name = "Asha";
console.log(name, age, height, isStudent);
console.log(typeof age, typeof isStudent, typeof name, typeof null, typeof undefined, typeof 10n);
console.log(Number("88") + 2, String(90) + "!", parseInt("42px"), 0.1 + 0.2);
console.log(Number.isInteger(5), Number.isInteger(5.5), Number.MAX_SAFE_INTEGER);

✅ Verified output

Asha 15 1.62 true
number boolean string object undefined bigint
90 90! 42 0.30000000000000004
true false 9007199254740991
Operators and boolean logic

Use === (strict equal) instead of ==, which converts types. && || ! are the logical operators; ?? gives a default only for null or undefined.

const a = 17, b = 5;
console.log(a + b, a - b, a * b, a / b, Math.floor(a / b), a % b, a ** 2);
console.log(5 == "5", 5 === "5", 0 == false, 0 === false);
const hasTicket = true, isVip = false;
console.log("enter:", hasTicket && !isVip, "| either:", hasTicket || isVip);
const nickname = null;
console.log(nickname ?? "no nickname", 0 || "zero is falsy", 0 ?? "kept");

✅ Verified output

22 12 85 3.4 3 2 289
true false true false
enter: true | either: true
no nickname zero is falsy 0
Conditionals: if, else, switch, ternary

if/else chooses a branch, switch compares one value with many cases, and the ternary a ? b : c is a short if/else that gives a value.

const marks = 78;
let grade;
if (marks >= 90) grade = "A+";
else if (marks >= 75) grade = "A";
else if (marks >= 35) grade = "Pass";
else grade = "Fail";
console.log("Grade:", grade);

const day = "sat";
switch (day) {
  case "sat":
  case "sun":
    console.log("Weekend");
    break;
  default:
    console.log("School day");
}
console.log(marks >= 35 ? "passed" : "try again");

✅ Verified output

Grade: A
Weekend
passed
Loops: for, while, for...of, break, continue

for counts, while repeats on a condition, for...of walks arrays and strings. break stops and continue skips one turn.

for (let i = 1; i <= 5; i++) {
  if (i === 3) continue;
  console.log("for", i);
}
let n = 10;
while (n > 0) {
  if (n < 4) break;
  console.log("while", n);
  n -= 3;
}
for (const ch of "abc") console.log("char", ch);
for (let r = 1; r <= 3; r++) {
  let row = "";
  for (let c = 1; c <= 3; c++) row += String(r * c).padStart(3);
  console.log(row);
}

✅ Verified output

for 1
for 2
for 4
for 5
while 10
while 7
while 4
char a
char b
char c
  1  2  3
  2  4  6
  3  6  9
Functions, arrow functions and scope

Functions can have default parameters and rest parameters. Arrow functions are a shorter syntax. Variables declared with let/const live only inside their block.

function area(length, width = 1) {
  return length * width;
}
const greet = (name, greeting = "Namaste") => `${greeting}, ${name}!`;
const stats = (...nums) => [Math.min(...nums), Math.max(...nums), nums.reduce((s, x) => s + x, 0) / nums.length];

console.log(area(5, 3), area(7));
console.log(greet("Ravi"), greet("Meena", "Hello"));
const [low, high, avg] = stats(4, 9, 2, 7);
console.log(low, high, avg);
{
  const inside = "block scope";
  console.log(inside);
}
console.log(typeof inside);

✅ Verified output

15 7
Namaste, Ravi! Hello, Meena!
2 9 5.5
block scope
undefined

🌿 Intermediate (7)

Arrays

Arrays are ordered lists. push adds, sort orders (give a compare function for numbers!), and map/filter/reduce transform them without loops.

const marks = [72, 95, 64, 88];
marks.push(91);
marks.sort((x, y) => x - y);
console.log(marks, "first:", marks[0], "last:", marks.at(-1), "top 2:", marks.slice(-2));
console.log([10, 9, 1].sort(), "<- default sort compares text!");
const oddSquares = [1, 2, 3, 4, 5].filter((x) => x % 2).map((x) => x * x);
console.log("odd squares:", oddSquares, "sum:", oddSquares.reduce((s, x) => s + x, 0));
const [first, ...rest] = marks;
console.log(first, rest);

✅ Verified output

[ 64, 72, 88, 91, 95 ] first: 64 last: 95 top 2: [ 91, 95 ]
[ 1, 10, 9 ] <- default sort compares text!
odd squares: [ 1, 9, 25 ] sum: 35
64 [ 72, 88, 91, 95 ]
Strings and template literals

Strings are immutable. Template literals use backticks and ${} for values. Useful methods: trim, toUpperCase, split, join, replace, includes, padStart.

const s = "  GayaGnan learning  ";
const t = s.trim();
console.log(t.toUpperCase(), "|", t.replace("learning", "labs"), "|", t.length);
const words = t.split(" ");
console.log(words, "->", words.join("-"));
const price = 49.5, qty = 3;
console.log(`Total: ₹${(price * qty).toLocaleString("en-IN", { minimumFractionDigits: 2 })} for ${qty} items`);
console.log("palindrome:", "level" === [..."level"].reverse().join(""), t.includes("Gnan"));

✅ Verified output

GAYAGNAN LEARNING | GayaGnan labs | 17
[ 'GayaGnan', 'learning' ] -> GayaGnan-learning
Total: ₹148.50 for 3 items
palindrome: true true
Objects, Map and Set

Plain objects hold named properties. Map is a key-value store with any key type; Set keeps unique values.

const stock = { pen: 40, book: 12 };
stock.eraser = 25;
stock.pen -= 5;
for (const [item, count] of Object.entries(stock).sort()) console.log(item, count);
console.log("has ruler?", "ruler" in stock);
const a = new Set(["maths", "science", "art"]), b = new Set(["science", "music"]);
console.log("both:", [...a].filter((x) => b.has(x)), "| either:", [...new Set([...a, ...b])].sort());
const freq = new Map();
for (const w of "the cat and the hat and the bat".split(" ")) freq.set(w, (freq.get(w) || 0) + 1);
console.log(Object.fromEntries(freq));

✅ Verified output

book 12
eraser 25
pen 35
has ruler? false
both: [ 'science' ] | either: [ 'art', 'maths', 'music', 'science' ]
{ the: 3, cat: 1, and: 2, hat: 1, bat: 1 }
Classes and private fields

class bundles data and methods. Fields starting with # are truly private: code outside the class cannot read them.

class BankAccount {
  #balance;
  constructor(owner, balance = 0) {
    this.owner = owner;
    this.#balance = balance;
  }
  deposit(amount) {
    if (amount <= 0) throw new RangeError("amount must be positive");
    this.#balance += amount;
  }
  get balance() {
    return this.#balance;
  }
}
const acc = new BankAccount("Asha", 500);
acc.deposit(250);
console.log(acc.owner, acc.balance, Object.keys(acc));

✅ Verified output

Asha 750 [ 'owner' ]
Inheritance and polymorphism

extends makes a subclass; super calls the parent. Each subclass overrides area(), and the same loop works for all shapes.

class Shape {
  area() { throw new Error("not implemented"); }
  toString() { return `${this.constructor.name} with area ${this.area().toFixed(2)}`; }
}
class Circle extends Shape {
  constructor(r) { super(); this.r = r; }
  area() { return Math.PI * this.r ** 2; }
}
class Rect extends Shape {
  constructor(w, h) { super(); this.w = w; this.h = h; }
  area() { return this.w * this.h; }
}
for (const s of [new Circle(1), new Rect(3, 4)]) console.log(String(s), s instanceof Shape);

✅ Verified output

Circle with area 3.14 true
Rect with area 12.00 true
Errors and exceptions

try/catch/finally handles errors. throw raises one; custom error classes extend Error. JSON.parse throws on bad input.

function safeParse(text) {
  try {
    return JSON.parse(text);
  } catch (e) {
    console.log("bad JSON:", e.name);
    return null;
  } finally {
    console.log("checked", text);
  }
}
console.log(safeParse('{"marks": 88}'));
console.log(safeParse("{marks: 88}"));
class ValidationError extends Error {}
try {
  throw new ValidationError("age must be 0-120");
} catch (e) {
  console.log(e instanceof ValidationError, e.message);
}

✅ Verified output

checked {"marks": 88}
{ marks: 88 }
bad JSON: SyntaxError
checked {marks: 88}
null
true age must be 0-120
Files with Node.js

In Node.js the fs module reads and writes files (browsers cannot touch your disk). Here we write a CSV to the temp folder and read it back.

const fs = require("fs"), os = require("os"), path = require("path");
const file = path.join(os.tmpdir(), "marks.csv");
fs.writeFileSync(file, "name,marks\nAsha,88\nRavi,95\n");
const rows = fs.readFileSync(file, "utf8").trim().split("\n").slice(1).map((l) => {
  const [name, marks] = l.split(",");
  return { name, marks: Number(marks) };
});
console.log(rows);
console.log("average:", rows.reduce((s, r) => s + r.marks, 0) / rows.length);
fs.unlinkSync(file);

✅ Verified output

[ { name: 'Asha', marks: 88 }, { name: 'Ravi', marks: 95 } ]
average: 91.5

🌳 Advanced (4)

Recursion and memoization

A recursive function solves a smaller version of itself. A Map cache (memoization) makes fib(80) instant; BigInt keeps the large answer exact.

const memo = new Map();
function fib(n) {
  if (n < 2) return BigInt(n);
  if (memo.has(n)) return memo.get(n);
  const v = fib(n - 1) + fib(n - 2);
  memo.set(n, v);
  return v;
}
function binarySearch(a, target, lo = 0, hi = a.length - 1) {
  if (lo > hi) return -1;
  const mid = (lo + hi) >> 1;
  if (a[mid] === target) return mid;
  return a[mid] < target ? binarySearch(a, target, mid + 1, hi) : binarySearch(a, target, lo, mid - 1);
}
console.log(Array.from({ length: 10 }, (_, i) => Number(fib(i))), String(fib(80)));
console.log(binarySearch([2, 5, 8, 12, 16, 23, 38], 23));

✅ Verified output

[
  0, 1,  1,  2,  3,
  5, 8, 13, 21, 34
] 23416728348467685
5
Higher-order functions and closures

Functions can return functions. A closure remembers variables from where it was made: here each counter keeps its own count.

const applyTwice = (f, x) => f(f(x));
function makeCounter(step = 1) {
  let count = 0;
  return () => (count += step);
}
const byOne = makeCounter(), byTen = makeCounter(10);
byOne(); byOne();
console.log(byOne(), byTen(), byTen());
const students = [["Asha", 88], ["Ravi", 95], ["Meena", 72]];
console.log(students.toSorted ? "toSorted available" : "sort copy", [...students].sort((a, b) => b[1] - a[1]));
console.log(applyTwice((n) => n * 3, 2), applyTwice((s) => s + "!", "hi"));
const compose = (...fns) => (x) => fns.reduceRight((v, f) => f(v), x);
console.log(compose((x) => x + 1, (x) => x * 2)(5));

✅ Verified output

3 10 20
toSorted available [ [ 'Ravi', 95 ], [ 'Asha', 88 ], [ 'Meena', 72 ] ]
18 hi!!
11
Asynchronous code: promises and async/await

JavaScript runs one thing at a time but does not wait for timers or network. Promise.all runs the waits together, so three 200 ms tasks take about 200 ms.

const wait = (ms, v) => new Promise((ok) => setTimeout(() => ok(v), ms));
async function main() {
  const t = Date.now();
  const pages = await Promise.all([wait(200, "page0"), wait(200, "page1"), wait(200, "page2")]);
  console.log("all:", pages, "fast:", Date.now() - t < 400);
  const first = await Promise.race([wait(300, "slow"), wait(100, "quick")]);
  console.log("race:", first);
  try {
    await Promise.reject(new Error("network down"));
  } catch (e) {
    console.log("caught:", e.message);
  }
}
console.log("before main finishes");
main();

✅ Verified output

before main finishes
all: [ 'page0', 'page1', 'page2' ] fast: true
race: quick
caught: network down
References, copying and immutability

Objects and arrays are shared by reference. Spread makes a shallow copy; structuredClone makes a deep copy; Object.freeze stops changes.

const a = { name: "Asha", marks: [88, 92] };
const b = a;
const c = { ...a };
const d = structuredClone(a);
a.marks.push(75);
a.name = "Asha R";
console.log("b", b.name, b.marks, b === a);
console.log("c", c.name, c.marks);
console.log("d", d.name, d.marks);
const frozen = Object.freeze({ pi: 3.14 });
frozen.pi = 3;
console.log("frozen:", frozen.pi, Object.isFrozen(frozen));

✅ Verified output

b Asha R [ 88, 92, 75 ] true
c Asha [ 88, 92, 75 ]
d Asha [ 88, 92 ]
frozen: 3.14 true

🧪 Browser workspace

Runs in a sandbox inside your browser with a time limit: no install needed, and your code never reaches our server.

Loading the workspace…

🛠️ Set up and verify

  1. Install
    winget install OpenJS.NodeJS.LTS
    brew install node
    sudo apt install nodejs npm
  2. Editor: Visual Studio Code with ESLint, Prettier.
  3. Create hello.js
    console.log('Hello, GayaGnan!');
  4. Run it and check the version
    node hello.js
    node --version
  5. Health check: paste what your terminal printed.

Install one language at a time. These commands only install or print versions; nothing here deletes files. Versions change: check the official page and note the version you installed.

🧭 The 14-lab path

  • 00 · Setup and verify — install the runtime and editor, run hello world, print the version, fix PATH
  • 01 · Syntax and trace — follow each line and the value of every variable
  • 02 · Logic — conditionals and decision trees
  • 03 · Loops — trace tables and loop challenges
  • 04 · Functions — break problems down and test each piece
  • 05 · Data structures — lists, maps, stacks, queues and trees you can see
  • 06 · Debugging — bug cases with a hint ladder
  • 07 · Algorithms — search, sort and Big-O comparison
  • 08 · Files and data — read and write fixture files
  • 09 · API or database — talk to a mock API or a sandbox database 🧪 REST Request & Response
  • 10 · Testing — write tests and read failing assertions
  • 11 · Security — secure coding and dependency hygiene for this language 🧪 Authentication with Fake Identities
  • 12 · Project — one portfolio mini-project
  • 13 · Assessment — quiz, coding test, rubric and an explain-your-answer prompt

📚 Modules

  1. variables and types
  2. operators
  3. conditionals
  4. loops
  5. functions
  6. arrays and objects
  7. DOM
  8. events
  9. modules
  10. promises
  11. async/await
  12. fetch with mock APIs
  13. error handling
  14. Node CLI
  15. unit tests (Vitest/Jest)
  16. security and accessibility basics

🏗️ Mini-projects

  • Interactive quiz
  • Calculator
  • To-do app
  • Accessible dashboard
  • Mock API client
  • Simple Node REST API

Projects use synthetic data only.