Chapters: JavaScript HTML & CSS JSON XML YAML Go Java ← Full TOC

🔥 Chapter 30 — JavaScript & Node.js

Complete reference for modern JavaScript (ES6+) and Node.js — arrays, promises, async/await, DOM, fetch, HTTP servers, and Express with copy-paste examples.
Part of The Direct Path to Linux Ubuntu — free for all.

5Topics
143+Methods
5Examples
nodeRun command
ES2024Version
FreeNo login
⚡ ES6+ Core 📋 Arrays ⏳ Async/Promises 🌐 DOM & Browser 🟢 Node.js ⚡ Examples

⚡ ES6+ Core

⚡ ES6+ CoreModern JavaScript — let/const, arrow functions, destructuring, spread

📋 Arrays

📋 Arrays & IterationArray methods — map, filter, reduce, find, flat, sort

⏳ Async/Promises

⏳ Promises & AsyncAsync/await, Promise, fetch — asynchronous JavaScript

🌐 DOM & Browser

🌐 DOM & BrowserDOM manipulation, events, localStorage, fetch in browser

🟢 Node.js

🟢 Node.jsNode.js — fs, http, path, process, npm modules

⚡ Quick Examples

Run Node.js files with node script.js. Browser files save as .html and open in browser.

Hello, JavaScript!

Variables, functions, and modern JS syntax.

// Hello JavaScript — ES6+ style
const greet = (name, lang = 'JavaScript') =>
  `Hello, \${name}! Welcome to \${lang} \${typeof Symbol !== 'undefined' ? '⚡' : ''}`;

console.log(greet('MyWebUniversity'));
console.log(greet('World', 'Node.js'));

// Destructuring + computed properties
const langs = ['Python','Java','Ruby','Rust','Go','JavaScript'];
const [first, , third, ...others] = langs;
console.log({ first, third, others });

// Numbers and math
console.log([1,2,3,4,5].reduce((sum,n) => sum + n, 0));   // 15
console.log(Array.from({length:5}, (_,i) => (i+1)**2));    // [1,4,9,16,25]
console.log(Math.max(...[3,1,4,1,5,9,2,6]));               // 9

// String methods
const csv = 'Alice,95,Math;Bob,87,Science;Carol,92,Math';
const rows = csv.split(';').map(row => {
  const [name, score, subject] = row.split(',');
  return { name, score: +score, subject };
});
console.log(JSON.stringify(rows, null, 2));
// node hello.js

Classes & Modules

ES6 classes, inheritance, and module pattern.

// ES6 Classes & Inheritance
class EventEmitter {
  #listeners = new Map();
  on(event, fn)  { (this.#listeners.get(event) || this.#listeners.set(event,[]).get(event)).push(fn); return this; }
  off(event, fn) { this.#listeners.set(event, (this.#listeners.get(event)||[]).filter(f=>f!==fn)); return this; }
  emit(event, ...args) { (this.#listeners.get(event)||[]).forEach(fn=>fn(...args)); return this; }
}

class Database extends EventEmitter {
  #data = new Map();
  set(key, value) { this.#data.set(key, value); this.emit('write', key, value); return this; }
  get(key)        { return this.#data.get(key); }
  delete(key)     { const had = this.#data.delete(key); if(had) this.emit('delete', key); return had; }
  keys()          { return [...this.#data.keys()]; }
  size()          { return this.#data.size; }
  toJSON()        { return Object.fromEntries(this.#data); }
}

const db = new Database();
db.on('write',  (k,v) => console.log(`  WRITE  \${k} = \${JSON.stringify(v)}`));
db.on('delete', (k)   => console.log(`  DELETE \${k}`));

db.set('user:1', { name: 'Alice', score: 95 })
  .set('user:2', { name: 'Bob',   score: 87 })
  .set('config', { theme: 'dark', lang: 'en' });

console.log('Keys:', db.keys());
console.log('user:1:', db.get('user:1'));
db.delete('config');
console.log('JSON:', JSON.stringify(db.toJSON(), null, 2));
// node classes.js

Async/Await & Error Handling

Practical async patterns with retries and timeouts.

// Async/Await patterns
const delay  = ms => new Promise(r => setTimeout(r, ms));
const random = (min, max) => Math.floor(Math.random() * (max-min+1)) + min;

// Simulate flaky API
const unstableApi = async (id) => {
  await delay(random(10, 50));
  if (Math.random() < 0.4) throw new Error(`API timeout for id \${id}`);
  return { id, data: `result-\${id}`, timestamp: Date.now() };
};

// Retry with exponential backoff
async function withRetry(fn, maxRetries = 3, baseDelay = 50) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (err) {
      if (attempt === maxRetries) throw err;
      const wait = baseDelay * 2 ** (attempt - 1);
      console.log(`  Attempt \${attempt} failed: \${err.message}. Retrying in \${wait}ms...`);
      await delay(wait);
    }
  }
}

// Promise with timeout
function withTimeout(promise, ms) {
  const timeout = new Promise((_, reject) =>
    setTimeout(() => reject(new Error(`Timed out after \${ms}ms`)), ms));
  return Promise.race([promise, timeout]);
}

async function main() {
  // Parallel with retry
  const results = await Promise.allSettled(
    [1,2,3,4,5].map(id => withRetry(() => unstableApi(id)))
  );
  results.forEach((r, i) => {
    if (r.status === 'fulfilled') console.log(`✅ \${i+1}: \${r.value.data}`);
    else                          console.log(`❌ \${i+1}: \${r.reason.message}`);
  });
}
main();
// node async.js

Working with JSON & Objects

Deep cloning, object manipulation, and JSON patterns.

// Object & JSON patterns
// Deep clone
const original = { a: 1, b: { c: [1,2,3], d: { e: true } } };
const clone = structuredClone(original);
clone.b.c.push(4);
console.log('original.b.c:', original.b.c);  // [1,2,3] — unchanged
console.log('clone.b.c:   ', clone.b.c);     // [1,2,3,4]

// Object.entries / fromEntries
const prices = { apple: 1.20, banana: 0.50, cherry: 3.00 };
const discounted = Object.fromEntries(
  Object.entries(prices).map(([k,v]) => [k, +(v * 0.9).toFixed(2)])
);
console.log('Discounted:', discounted);

// Object.groupBy (ES2024)
const students = [
  {name:'Alice', subject:'Math', score:95},
  {name:'Bob',   subject:'Science', score:87},
  {name:'Carol', subject:'Math', score:92},
];
// Polyfill if not available
const groupBy = (arr, fn) => arr.reduce((acc, item) => {
  const key = fn(item);
  (acc[key] = acc[key] || []).push(item);
  return acc;
}, {});
const bySubject = groupBy(students, s => s.subject);
console.log(JSON.stringify(bySubject, null, 2));

// JSON.stringify with replacer and reviver
const data = { name: 'Alice', created: new Date('2026-01-01'), score: 95 };
const json = JSON.stringify(data, (key, val) =>
  val instanceof Date ? val.toISOString() : val, 2);
console.log(json);
const parsed = JSON.parse(json, (key, val) =>
  key === 'created' ? new Date(val) : val);
console.log('Parsed date:', parsed.created instanceof Date, parsed.created.getFullYear());
// node json.js

Express.js REST API

Full REST API with Express, middleware, and JSON.

// Express.js REST API
// npm install express
const express = require('express');
const app = express();
app.use(express.json());

// In-memory database
let students = [
  { id: 1, name: 'Alice',  subject: 'Math',    score: 95 },
  { id: 2, name: 'Bob',    subject: 'Science',  score: 87 },
  { id: 3, name: 'Carol',  subject: 'Math',    score: 92 },
];
let nextId = 4;

// Middleware: logger
app.use((req, res, next) => {
  console.log(`\${new Date().toISOString()} \${req.method} \${req.path}`);
  next();
});

// Routes
app.get('/students', (req, res) => {
  const { subject, minScore } = req.query;
  let data = students;
  if (subject)  data = data.filter(s => s.subject === subject);
  if (minScore) data = data.filter(s => s.score >= +minScore);
  res.json({ count: data.length, students: data });
});

app.get('/students/:id', (req, res) => {
  const s = students.find(s => s.id === +req.params.id);
  if (!s) return res.status(404).json({ error: 'Not found' });
  res.json(s);
});

app.post('/students', (req, res) => {
  const { name, subject, score } = req.body;
  if (!name || !subject || score == null)
    return res.status(400).json({ error: 'name, subject, score required' });
  const student = { id: nextId++, name, subject, score: +score };
  students.push(student);
  res.status(201).json(student);
});

app.put('/students/:id', (req, res) => {
  const idx = students.findIndex(s => s.id === +req.params.id);
  if (idx === -1) return res.status(404).json({ error: 'Not found' });
  students[idx] = { ...students[idx], ...req.body, id: students[idx].id };
  res.json(students[idx]);
});

app.delete('/students/:id', (req, res) => {
  const idx = students.findIndex(s => s.id === +req.params.id);
  if (idx === -1) return res.status(404).json({ error: 'Not found' });
  students.splice(idx, 1);
  res.json({ ok: true });
});

app.get('/stats', (req, res) => {
  const avg = students.reduce((sum,s) => sum+s.score,0) / students.length;
  res.json({ count: students.length, average: avg.toFixed(2),
             highest: Math.max(...students.map(s=>s.score)) });
});

app.listen(3000, () => console.log('API running on http://localhost:3000'));
// node api.js
// curl http://localhost:3000/students
// curl http://localhost:3000/students?subject=Math&minScore=90
// curl -X POST http://localhost:3000/students -H 'Content-Type:application/json' -d '{"name":"Eve","subject":"Math","score":98}'