thecodex.expert · The Codex Family of Knowledge
Snippets

JavaScript Snippets

14 idiomatic JavaScript patterns — copy, paste, adapt.

ES2022+ 14 snippets Verified
JavaScriptarray_methods.js
#9654; Try it
Array methods: map, filter, reduce, flat
const users = [
  { name: "Alice", age: 30, active: true },
  { name: "Bob",   age: 25, active: false },
  { name: "Carol", age: 35, active: true },
];

// map: transform each element
const names = users.map(u => u.name);         // ["Alice", "Bob", "Carol"]

// filter: keep matching elements
const active = users.filter(u => u.active);   // [Alice, Carol]

// reduce: fold to a single value
const totalAge = users.reduce((sum, u) => sum + u.age, 0);  // 90

// Chaining: active users sorted by age descending
const result = users
  .filter(u => u.active)
  .sort((a, b) => b.age - a.age)
  .map(u => u.name);
// ["Carol", "Alice"]

// flat and flatMap
const nested = [[1, 2], [3, 4], [5]];
console.log(nested.flat());            // [1, 2, 3, 4, 5]

const sentences = ["hello world", "foo bar"];
const words = sentences.flatMap(s => s.split(" "));
// ["hello", "world", "foo", "bar"]

// findIndex, at (ES2022), Array.from
const idx = users.findIndex(u => u.name === "Bob");  // 1
console.log(users.at(-1));  // last element: Carol
JavaScriptdestructuring.js
#9654; Try it
Destructuring and rest/spread
// Object destructuring with rename and default
const { name, age = 0, role: userRole = "guest" } = { name: "Alice", age: 30 };
// name = "Alice", age = 30, userRole = "guest" (renamed from role, defaulted)

// Array destructuring with skip
const [first, , third, ...rest] = [1, 2, 3, 4, 5];
// first=1, third=3, rest=[4,5]

// Nested destructuring
const { address: { city, zip } } = { address: { city: "Mumbai", zip: "400001" } };

// Function parameter destructuring
function renderUser({ name, age = 0, active = true }) {
  return `${name} (${age}) — ${active ? "active" : "inactive"}`;
}
renderUser({ name: "Alice", age: 30 });

// Spread: clone and merge objects
const base = { theme: "dark", lang: "en" };
const overrides = { lang: "hi", fontSize: 16 };
const config = { ...base, ...overrides };
// { theme: "dark", lang: "hi", fontSize: 16 }
// Later properties win — overrides replaces base.lang

// Spread arrays
const a = [1, 2, 3];
const b = [0, ...a, 4];  // [0, 1, 2, 3, 4]
JavaScriptasync_patterns.js
#9654; Try it
Async/await patterns and error handling
// Basic async/await
async function fetchUser(id) {
  const response = await fetch(`/api/users/${id}`);
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
}

// Sequential vs concurrent
async function sequential(ids) {
  const results = [];
  for (const id of ids) {
    results.push(await fetchUser(id));  // waits for each
  }
  return results;  // total time = sum of all requests
}

async function concurrent(ids) {
  // Promise.all: all start immediately, wait for all to finish
  return Promise.all(ids.map(id => fetchUser(id)));  // total = slowest request
}

// Promise.allSettled: get results even when some fail
async function resilient(ids) {
  const results = await Promise.allSettled(ids.map(fetchUser));
  return results.map(r =>
    r.status === "fulfilled" ? r.value : { error: r.reason.message }
  );
}

// Promise.race: take the first to resolve
async function withTimeout(promise, ms) {
  const timeout = new Promise((_, reject) =>
    setTimeout(() => reject(new Error("Timeout")), ms)
  );
  return Promise.race([promise, timeout]);
}
JavaScriptoptional_chaining.js
#9654; Try it
Optional chaining and nullish coalescing
const user = {
  name: "Alice",
  address: {
    city: "Mumbai",
  },
  getGreeting: () => "Hello!"
};

// Optional chaining (?.) — returns undefined instead of throwing
console.log(user.address?.city);         // "Mumbai"
console.log(user.address?.zip);          // undefined (no throw)
console.log(user.profile?.avatar?.url);  // undefined
console.log(user.getGreeting?.());       // "Hello!"
console.log(user.nonExistent?.());       // undefined

// Array optional chaining
const arr = null;
console.log(arr?.[0]);  // undefined

// Nullish coalescing (??) — only falls back on null/undefined (not 0 or "")
const count = user.postCount ?? 0;    // 0 if null/undefined
const name = user.name ?? "Anonymous"; // "Alice"
const zero = 0 ?? 42;                  // 0 — 0 is NOT null/undefined

// vs logical OR (||) — falls back on any falsy value
const zeroOr = 0 || 42;  // 42 — 0 is falsy

// Nullish assignment (??=)
user.score ??= 100;  // assigns only if user.score is null/undefined
JavaScriptclasses_modern.js
#9654; Try it
Classes with private fields (ES2022)
class BankAccount {
  // Private fields: truly private, not just convention
  #balance;
  #owner;
  #transactions = [];

  constructor(owner, initialBalance = 0) {
    this.#owner = owner;
    this.#balance = initialBalance;
  }

  deposit(amount) {
    if (amount <= 0) throw new RangeError("Amount must be positive");
    this.#balance += amount;
    this.#transactions.push({ type: "deposit", amount });
    return this;  // method chaining
  }

  withdraw(amount) {
    if (amount > this.#balance) throw new Error("Insufficient funds");
    this.#balance -= amount;
    this.#transactions.push({ type: "withdrawal", amount });
    return this;
  }

  // Getter: read-only computed property
  get balance() { return this.#balance; }
  get owner() { return this.#owner; }

  // Static method: factory
  static empty(owner) { return new BankAccount(owner, 0); }
}

const acc = BankAccount.empty("Alice").deposit(1000).withdraw(200);
console.log(acc.balance);  // 800
// acc.#balance  // SyntaxError: private field
JavaScriptiterators_generators.js
#9654; Try it
Generators and custom iterators
// Generator function: lazy value producer
function* range(start, end, step = 1) {
  for (let i = start; i < end; i += step) {
    yield i;
  }
}

console.log([...range(0, 10, 2)]);  // [0, 2, 4, 6, 8]

for (const n of range(1, 4)) {
  console.log(n);  // 1, 2, 3
}

// Infinite generator
function* naturals() {
  let n = 1;
  while (true) yield n++;
}

function take(n, iter) {
  const result = [];
  for (const val of iter) {
    result.push(val);
    if (result.length >= n) break;
  }
  return result;
}

console.log(take(5, naturals()));  // [1, 2, 3, 4, 5]

// Custom iterable object
const countdown = {
  from: 5,
  [Symbol.iterator]() {
    let current = this.from;
    return {
      next() {
        return current > 0
          ? { value: current--, done: false }
          : { value: undefined, done: true };
      }
    };
  }
};
console.log([...countdown]);  // [5, 4, 3, 2, 1]
JavaScriptmap_set.js
#9654; Try it
Map, Set, WeakMap, and WeakRef
// Map: any key type, insertion-order iteration
const map = new Map();
const keyObj = { id: 1 };
map.set(keyObj, "object key works");
map.set("string", 42);
map.set(true, "boolean key");

console.log(map.get(keyObj));  // "object key works"
console.log(map.size);         // 3

// Map from entries
const freq = new Map([["a", 3], ["b", 1], ["c", 2]]);
const sorted = [...freq.entries()].sort((a, b) => b[1] - a[1]);
// [["a",3], ["c",2], ["b",1]]

// Set: unique values, insertion order
const set = new Set([1, 2, 3, 2, 1]);
console.log([...set]);  // [1, 2, 3]

// Set operations (no built-in methods until ES2024)
const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);
const union = new Set([...a, ...b]);
const intersection = new Set([...a].filter(x => b.has(x)));
const difference = new Set([...a].filter(x => !b.has(x)));

// WeakMap: keys are objects, no memory leak when key is GC'd
const cache = new WeakMap();
function memoize(obj, compute) {
  if (!cache.has(obj)) cache.set(obj, compute(obj));
  return cache.get(obj);
}
JavaScriptobject_methods.js
#9654; Try it
Object.entries, groupBy, structuredClone
const scores = { alice: 95, bob: 87, carol: 92, dave: 87 };

// Object.entries/keys/values
Object.entries(scores).forEach(([name, score]) => {
  console.log(`${name}: ${score}`);
});

// Sort object by value
const ranked = Object.entries(scores)
  .sort(([, a], [, b]) => b - a)  // sort by value descending
  .map(([name]) => name);
// ["alice", "carol", "bob", "dave"]

// Object.fromEntries: entries back to object
const doubled = Object.fromEntries(
  Object.entries(scores).map(([k, v]) => [k, v * 2])
);

// Object.groupBy (ES2024)
const people = [
  { name: "Alice", dept: "eng" },
  { name: "Bob",   dept: "hr" },
  { name: "Carol", dept: "eng" },
];
// const byDept = Object.groupBy(people, p => p.dept);
// { eng: [Alice, Carol], hr: [Bob] }

// structuredClone: deep clone (replaces JSON.parse(JSON.stringify(...)))
const original = { a: 1, nested: { b: [2, 3] }, date: new Date() };
const clone = structuredClone(original);
clone.nested.b.push(4);
console.log(original.nested.b);  // [2, 3] — not affected
JavaScripterror_patterns.js
#9654; Try it
Custom errors and error handling patterns
// Custom Error subclass
class ValidationError extends Error {
  constructor(field, message) {
    super(message);
    this.name = "ValidationError";
    this.field = field;
    // Maintain proper stack trace in V8
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, ValidationError);
    }
  }
}

class NetworkError extends Error {
  constructor(statusCode, message) {
    super(message);
    this.name = "NetworkError";
    this.statusCode = statusCode;
  }
}

// Error handling with instanceof
async function loadUser(id) {
  try {
    const user = await fetchUser(id);
    return user;
  } catch (error) {
    if (error instanceof NetworkError && error.statusCode === 404) {
      return null;  // not found — not an error
    }
    throw error;  // re-throw unexpected errors
  }
}

// using declaration (ES2025 proposal — check browser support)
// try {
//   await using resource = acquireResource();
//   // resource.dispose() called automatically
// }
JavaScriptproxy_reflect.js
#9654; Try it
Proxy for validation and observation
// Proxy: intercept object operations
function createValidated(target, validators) {
  return new Proxy(target, {
    set(obj, prop, value) {
      if (validators[prop]) {
        const error = validators[prop](value);
        if (error) throw new TypeError(`${prop}: ${error}`);
      }
      return Reflect.set(obj, prop, value);  // Reflect: default behaviour
    },
    get(obj, prop) {
      console.log(`Reading ${prop}`);
      return Reflect.get(obj, prop);
    }
  });
}

const user = createValidated({}, {
  age: v => typeof v !== "number" ? "must be a number"
           : v < 0 ? "must be non-negative"
           : null,
  email: v => !v.includes("@") ? "must contain @" : null,
});

user.age = 25;        // ok
user.email = "a@b.c"; // ok
// user.age = -1;     // TypeError: age: must be non-negative
// user.email = "bad"; // TypeError: email: must contain @
JavaScriptmodules.mjs
#9654; Try it
ES modules: named, default, re-export
// math.mjs — named exports
export const PI = 3.14159;
export function add(a, b) { return a + b; }
export function multiply(a, b) { return a * b; }

// Default export: one per module
export default class Calculator {
  add(a, b) { return a + b; }
}

// main.mjs — importing
import Calculator, { add, PI } from "./math.mjs";
import * as math from "./math.mjs";  // namespace import

console.log(PI);         // 3.14159
console.log(add(1, 2));  // 3
console.log(math.multiply(3, 4));  // 12

// Rename on import
import { multiply as times } from "./math.mjs";

// Dynamic import: lazy load modules
async function loadFeature() {
  const { heavyFunction } = await import("./heavy.mjs");
  return heavyFunction();
}

// Re-export (barrel export pattern in index.mjs)
// export { add, multiply } from "./math.mjs";
// export { default as Calculator } from "./math.mjs";
JavaScripttemplate_literals.js
#9654; Try it
Tagged template literals
// Tagged template: function(strings, ...values)
// Used in: styled-components, gql, sql, html sanitisation

// Safe HTML escaping
function html(strings, ...values) {
  const escape = s => String(s)
    .replace(/&/g, "&")
    .replace(/</g, "<")
    .replace(/>/g, ">")
    .replace(/"/g, "&quot;");
  return strings.reduce((result, str, i) =>
    result + str + (values[i] !== undefined ? escape(values[i]) : ""), ""
  );
}

const userInput = '<script>alert("xss")</script>';
const safe = html`<p>Hello, ${userInput}!</p>`;
// <p>Hello, <script>alert(&quot;xss&quot;)</script>!</p>

// SQL tag (pattern — implement with your DB client)
function sql(strings, ...values) {
  const query = strings.reduce((q, str, i) => q + str + (i < values.length ? `$${i+1}` : ""), "");
  return { query, params: values };
}

const userId = 42;
const { query, params } = sql`SELECT * FROM users WHERE id = ${userId}`;
// query: "SELECT * FROM users WHERE id = $1"
// params: [42]
JavaScriptevent_emitter.js
#9654; Try it
Simple EventEmitter pattern
class EventEmitter {
  #listeners = new Map();

  on(event, handler) {
    if (!this.#listeners.has(event)) {
      this.#listeners.set(event, new Set());
    }
    this.#listeners.get(event).add(handler);
    return () => this.off(event, handler);  // returns unsubscribe function
  }

  off(event, handler) {
    this.#listeners.get(event)?.delete(handler);
  }

  once(event, handler) {
    const wrapper = (...args) => {
      handler(...args);
      this.off(event, wrapper);
    };
    return this.on(event, wrapper);
  }

  emit(event, ...args) {
    this.#listeners.get(event)?.forEach(handler => handler(...args));
  }
}

const bus = new EventEmitter();
const unsubscribe = bus.on("data", (payload) => console.log("received:", payload));
bus.once("connect", () => console.log("connected once"));

bus.emit("data", { id: 1 });  // received: { id: 1 }
bus.emit("connect");           // connected once
bus.emit("connect");           // (nothing — once handler removed itself)
unsubscribe();                 // clean up
JavaScripttyped_arrays.js
#9654; Try it
Typed arrays and ArrayBuffer for binary data
// ArrayBuffer: fixed raw memory block
const buffer = new ArrayBuffer(16);  // 16 bytes

// Views interpret the same buffer differently
const bytes  = new Uint8Array(buffer);     // 16 × uint8
const ints   = new Int32Array(buffer);     // 4 × int32
const floats = new Float64Array(buffer);   // 2 × float64

// Writing via one view is visible through others (same memory)
ints[0] = 0x41424344;  // "DCBA" in little-endian ASCII
console.log(String.fromCharCode(...bytes.slice(0, 4)));

// DataView: explicit endianness control for protocols/file formats
const dv = new DataView(buffer);
dv.setUint32(0, 1234567890, false);  // big-endian
dv.setFloat64(8, Math.PI, true);      // little-endian

console.log(dv.getFloat64(8, true));  // 3.141592653589793

// Practical: parse a binary message header
// const header = new DataView(response.arrayBuffer());
// const msgType = header.getUint16(0, false);
// const msgLen  = header.getUint32(2, false);
JavaScript referenceJS overview · Learn JavaScript
← Python Java snippets →
Everything JavaScript in one place — learning paths, reference, playground, and more. JavaScript Hub →