JavaScript Mastery — Read, edit, run, repeat.
⬅️ Back to Home

01 · Orientation

This interactive JS textbook focuses on fundamentals and the browser environment. All examples are runnable below.

What you'll learn
  • Syntax, data types, functions & closures
  • DOM, events, fetch & async/await
  • Debugging, performance, and security basics
Prereqs

Basic HTML/CSS are helpful.

Study flow
  1. Skim → run code
  2. Experiment by changing lines
  3. Take the quiz

02 · JS Basics

// Statements end with ; (optional). Use const/let, avoid var.
const name = "Lee"; let count = 0;
console.log(`Hi, ${name}!`);

Script placement: in <head defer> or at the end of <body>. Prefer type="module" for ESM.

03 · Types & Conversion

  • Primitives: string, number, bigint, boolean, undefined, symbol, null
  • Objects (arrays, functions, dates, etc.)
  • Type checks: typeof, Array.isArray(), instanceof
Number("42") // 42
Boolean("") // false
JSON.parse('{"ok":true}') // { ok: true }

04 · Operators

  • + - * / ** %; ++ --; += etc.
  • == vs === (prefer strict ===)
  • Nullish coalescing ??, optional chaining ?.
const port = config?.port ?? 3000; // default if null/undefined

05 · Control Flow

if (x > 10) {...} else {...}
switch(kind){ case 'a': ...; break; default: ... }
for (const item of list) {...}
while(cond){ ... }

06 · Functions

function add(a,b){ return a+b }
const mul = (a,b) => a*b; // arrow fn
function withDefault(a=1){ return a }

Arrows don't have their own this or arguments.

07 · Scope, Hoisting, Closures

function counter(){ let n=0; return ()=> ++n }
const c = counter(); c(); c(); // 1, 2 (closure keeps state)

let/const are block-scoped; var is function-scoped. Declarations hoist; initializations don't.

08 · Objects & Arrays

const user = { id:1, name:'Ada' };
const {name} = user; // destructuring
const arr = [1,2,3]; const [a,,c] = arr;
const withMore = {...user, role:'admin'}; // spread

09 · Prototypes & Classes

class Person{ constructor(name){ this.name=name } greet(){ return `Hi ${this.name}` } }
class Dev extends Person{ code(){ return 'typing…' } }

10 · Modules (ESM)

// math.js
export const add = (a,b) => a+b;
// app.js
import { add } from './math.js';

Use <script type="module" src="app.js" defer>. Modules are deferred by default.

11 · DOM Essentials

const el = document.querySelector('#app');
el.textContent = 'Hello';
el.insertAdjacentHTML('beforeend', '');

Batch DOM changes to reduce reflows; use documentFragment for large inserts.

12 · Events & Delegation

document.addEventListener('click', e => {
  if(e.target.matches('[data-action="remove"]')){ /* handle */ }
});

Use delegation for dynamic lists; remember passive: true on scroll/touch listeners when appropriate.

13 · Promises & Async/Await

const delay = ms => new Promise(r => setTimeout(r, ms));
(async () => { await delay(300); console.log('done') })();

14 · Fetch API & JSON

async function getUser(){
  const res = await fetch('https://jsonplaceholder.typicode.com/users/1');
  if(!res.ok) throw new Error('HTTP '+res.status);
  return res.json();
}
getUser().then(console.log).catch(console.error);

Include headers, handle errors, and consider AbortController for cancellations.

15 · Errors & Debugging

try{ risky() } catch(err){ console.error(err.message) } finally{ /* cleanup */ }
console.table([{id:1},{id:2}]);

Use DevTools: breakpoints, watch expressions, network panel.

16 · Storage & Cookies

localStorage.setItem('theme','dark');
sessionStorage.getItem('key');
document.cookie = 'name=value; SameSite=Lax; Secure';

17 · Timers & Animation Loop

const id = setInterval(() => console.log('tick'), 1000);
requestAnimationFrame(t => {/* smooth animations */});

18 · Regular Expressions

/^\w+@[\w.-]+\.[a-z]{2,}$/i.test('dev@example.com') // true

19 · Date, Intl & Number

const d = new Date('2025-01-01');
new Intl.DateTimeFormat('en-GB',{dateStyle:'long'}).format(d);
new Intl.NumberFormat('el-GR',{style:'currency',currency:'EUR'}).format(1234.56);

20 · Map/Set & Weak Collections

const m = new Map([[1,'one']]); m.get(1);
const s = new Set([1,2,2]); // {1,2}

21 · Iterators & Generators

function* idGen(){ let i=0; while(true) yield ++i }
const g = idGen(); g.next().value; // 1

22 · this, bind/call/apply

function greet(){ console.log(this.name) }
const user = { name:'Mina', greet };
const fn = greet.bind({ name:'Bound' }); fn(); // Bound

23 · Array Methods (map/filter/reduce)

const nums=[1,2,3,4];
nums.filter(n => n%2===0).map(n => n*n).reduce((a,b) => a+b, 0); // 20

24 · Patterns (FP/OOP/Modules)

  • Pure functions, immutability, composition
  • Factory vs class; module pattern with ESM
  • Event emitter; pub/sub basics

25 · Security Basics (XSS)

Never insert untrusted HTML; prefer textContent. Sanitize if necessary. Use rel="noopener" for target="_blank".

26 · Performance Tips

  • Debounce/throttle scroll/resize handlers
  • Use requestIdleCallback for non-urgent work
  • Virtualize long lists; avoid forced sync layout

27 · Live Code Runner

28 · Quick Quiz

1) Which statement about let/const is true?
2) What does await require?
3) Safest way to add user text into the DOM?

29 · Roadmap & Resources

  1. JS Foundations (this page)
  2. Build components: tabs, modal, dropdown, carousel, toast
  3. Fetch + caching layer, abortable requests
  4. Testing intro (Vitest/Jest) & accessibility checks

Bookmarks: MDN JS, web.dev, JavaScript.info.

`; run(); } document.getElementById('copy').onclick = async () => { await navigator.clipboard.writeText(editor.value); alert('Code copied to clipboard'); } run(); // Quiz const answers = JSON.parse(document.querySelector('.quiz').dataset.answers); document.getElementById('check').onclick = () => { let score = 0; let total = Object.keys(answers).length; for (const [q, a] of Object.entries(answers)){ const chosen = document.querySelector(`input[name="${q}"]:checked`); if(chosen && chosen.value === a) score++; } const out = document.getElementById('quizResult'); out.textContent = `You scored ${score}/${total}. ${score===total? 'Perfect! ✅' : score>=2? 'Nice! Keep going.' : 'Review the sections and retry.'}`; out.style.color = score===total ? 'var(--ok)' : 'var(--warn)'; }