# Code Reference — JavaScript

_119 pages_

---
# JavaScript (/docs/javascript)



# JavaScript [#javascript]

Language, async, modules, DOM.

Browse the sidebar for every cheat sheet in this section.

## Sections [#sections]

* [Dom](./dom)
* [Examples](./examples)


---

# AbortController (/docs/javascript/abort-controller)



# AbortController [#abortcontroller]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`AbortController` and `AbortSignal` cancel async operations — `fetch`, streams, and custom tasks. Create a controller, pass `signal` to APIs, call `abort()` to reject pending work and run abort listeners. Essential for timeouts, navigation changes, and avoiding race conditions.

## 🔧 Core concepts [#-core-concepts]

* **`new AbortController()`** → `\{ signal, abort(reason?) \}`.
* **`signal.aborted`*&#x2A;, &#x2A;*`signal.reason`*&#x2A;, &#x2A;*`signal.throwIfAborted()`**.
* **`signal.addEventListener("abort", ...)`** — once fired, stays aborted.
* **`AbortSignal.timeout(ms)`**: auto-abort after delay.
* **`AbortSignal.any([s1, s2])`**: abort when any aborts (modern).
* **Fetch**: `fetch(url, \{ signal \})` rejects with `AbortError` / `TimeoutError`.

```js
const c = new AbortController();
fetch("/api", { signal: c.signal }).catch((e) => {
  if (e.name === "AbortError") return;
  throw e;
});
c.abort();
```

## 💡 Examples [#-examples]

```js
// Timeout via helper
const data = await fetch("/slow", {
  signal: AbortSignal.timeout(5000),
}).then((r) => r.json());

// Manual timeout
const c = new AbortController();
const t = setTimeout(() => c.abort("timeout"), 3000);
try {
  await fetch("/api", { signal: c.signal });
} finally {
  clearTimeout(t);
}

// Cancel on new request (race guard)
let current;
function search(q) {
  current?.abort();
  current = new AbortController();
  return fetch(`/search?q=${encodeURIComponent(q)}`, {
    signal: current.signal,
  });
}

// Custom abortable work
function sleep(ms, signal) {
  return new Promise((resolve, reject) => {
    signal?.throwIfAborted();
    const id = setTimeout(resolve, ms);
    signal?.addEventListener(
      "abort",
      () => {
        clearTimeout(id);
        reject(signal.reason ?? new DOMException("Aborted", "AbortError"));
      },
      { once: true },
    );
  });
}

// Combine signals
const userCancel = new AbortController();
const signal = AbortSignal.any([userCancel.signal, AbortSignal.timeout(10_000)]);
```

```js
// Event listener option
el.addEventListener("click", handler, { signal: c.signal });
c.abort(); // removes listener
```

## ⚠️ Pitfalls [#️-pitfalls]

* Aborted fetch throws — always handle `AbortError` so UI doesn’t treat cancel as failure.
* Reusing an already-aborted signal keeps operations aborted — create a new controller per run.
* Not all APIs support signals yet — wrap manually with listeners.
* `abort(reason)` reason support varies; check `signal.reason`.
* Forgetting to abort on unmount leaks in-flight requests.

## 🔗 Related [#-related]

* [fetch.md](/docs/javascript/fetch) — fetch + signal
* [timers.md](/docs/javascript/timers) — timeout patterns
* [promise.md](/docs/javascript/promise) — rejection handling
* [DOM/events.md](/docs/javascript/dom/events) — signal option
* [event\_loop.md](/docs/javascript/event-loop) — async cancellation


---

# Web APIs (/docs/javascript/api)



# Web APIs [#web-apis]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

Browser and runtime **Web APIs** sit beside the language core: timers, encoding, crypto, streams, and platform globals. This sheet covers common non-DOM APIs you use from scripts. Prefer standards-based APIs over legacy vendor methods.

## 🔧 Core concepts [#-core-concepts]

* **Globals**: `globalThis`, `window` (browsers), `self` (workers).
* **Timers**: `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `queueMicrotask`.
* **Encoding**: `TextEncoder` / `TextDecoder`, `btoa` / `atob` (binary strings).
* **Crypto**: `crypto.getRandomValues`, `crypto.randomUUID`, `crypto.subtle`.
* **Streams**: `ReadableStream`, `WritableStream`, `TransformStream`.
* **Abort**: `AbortController` / `AbortSignal` cancel async work.
* **Structured clone**: `structuredClone(value)` deep-copies most data.

```js
const id = crypto.randomUUID();
const bytes = crypto.getRandomValues(new Uint8Array(16));
const copy = structuredClone({ nested: [1, 2, 3] });
```

## 💡 Examples [#-examples]

```js
// Debounced timer
function debounce(fn, ms) {
  let t;
  return (...args) => {
    clearTimeout(t);
    t = setTimeout(() => fn(...args), ms);
  };
}

// Abortable delay
function delay(ms, signal) {
  return new Promise((resolve, reject) => {
    const id = setTimeout(resolve, ms);
    signal?.addEventListener("abort", () => {
      clearTimeout(id);
      reject(signal.reason ?? new DOMException("Aborted", "AbortError"));
    }, { once: true });
  });
}

const ac = new AbortController();
await delay(1000, ac.signal).catch((e) => console.warn(e.name));

// Text encode / decode
const enc = new TextEncoder();
const dec = new TextDecoder();
const buf = enc.encode("café");
console.log(dec.decode(buf)); // café

// Base64 of binary (safe path)
function toBase64(bytes) {
  let s = "";
  for (const b of bytes) s += String.fromCharCode(b);
  return btoa(s);
}

// Subtle crypto digest
async function sha256(text) {
  const data = new TextEncoder().encode(text);
  const hash = await crypto.subtle.digest("SHA-256", data);
  return [...new Uint8Array(hash)]
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("");
}

// Microtask vs macrotask
queueMicrotask(() => console.log("micro"));
setTimeout(() => console.log("macro"), 0);
Promise.resolve().then(() => console.log("promise"));
// Order: micro, promise, macro
```

```js
// Simple transform stream (uppercase)
const upper = new TransformStream({
  transform(chunk, controller) {
    controller.enqueue(chunk.toUpperCase());
  },
});

const reader = new ReadableStream({
  start(c) {
    c.enqueue("hello");
    c.close();
  },
}).pipeThrough(upper).getReader();

const { value } = await reader.read();
console.log(value); // HELLO
```

## ⚠️ Pitfalls [#️-pitfalls]

* `btoa` / `atob` expect Latin-1 binary strings — not UTF-8 text directly.
* Timer IDs are numbers in browsers, objects in Node — always store and clear the return value.
* `crypto.subtle` needs a secure context (`https:` or `localhost`).
* `structuredClone` cannot clone functions, DOM nodes, or some host objects.
* Unhandled timer callbacks still run after navigation in some cases — clear on teardown.

## 🔗 Related [#-related]

* [fetch.md](/docs/javascript/fetch) — HTTP via Fetch API
* [promise.md](/docs/javascript/promise) — async primitives
* [async.md](/docs/javascript/async) — async/await patterns
* [encode.md](/docs/javascript/encode) — URI and percent-encoding
* [url.md](/docs/javascript/url) — URL / URLSearchParams
* [error.md](/docs/javascript/error) — AbortError and exceptions
* [DOM/window.md](/docs/javascript/dom/window) — window globals
* [DOM/events.md](/docs/javascript/dom/events) — event targets


---

# Arrays (/docs/javascript/arrays)



# Arrays [#arrays]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

Arrays are ordered, indexable lists. Prefer non-mutating methods (`map`, `filter`, `toSorted`) when state is shared; mutate in place only when you own the array. Watch sparse holes and default string `sort`.

## 🔧 Core concepts [#-core-concepts]

**Create / static**

| Method                       | Notes                                                |
| ---------------------------- | ---------------------------------------------------- |
| `Array()`, `[]`              | Prefer `[]`; `new Array(n)` makes length-n sparse    |
| `Array.of(...items)`         | Items as elements (avoids single-number length trap) |
| `Array.from(iter, mapFn?)`   | From iterable/array-like; optional map               |
| `Array.isArray(x)`           | True only for real arrays                            |
| `Array.fromAsync(asyncIter)` | Await each yield (ES2024)                            |

**Access / length**

| API                   | Notes                                         |
| --------------------- | --------------------------------------------- |
| `arr[i]`, `arr.at(i)` | `at` supports negatives                       |
| `arr.length`          | Writable; shrink truncates; grow adds holes   |
| `arr.with(i, v)`      | Copy with index `i` set to `v` (non-mutating) |

**Mutating**

| Method                      | Notes                                            |
| --------------------------- | ------------------------------------------------ |
| `push(...x)` / `pop()`      | End insert / remove                              |
| `unshift(...x)` / `shift()` | Start insert / remove (O(n))                     |
| `splice(i, n, ...x)`        | Delete `n` from `i`, insert `x`; returns removed |
| `sort(cmp?)`                | In-place; default **string** order               |
| `reverse()`                 | In-place reverse                                 |
| `fill(v, start?, end?)`     | Fill range with `v`                              |
| `copyWithin(t, s, e?)`      | Copy slice within same array                     |

**Non-mutating (ES2023+)**

| Method                  | Notes                                  |
| ----------------------- | -------------------------------------- |
| `toSorted(cmp?)`        | Sorted copy                            |
| `toReversed()`          | Reversed copy                          |
| `toSpliced(i, n, ...x)` | Splice copy                            |
| `slice(start?, end?)`   | Subarray copy (end exclusive)          |
| `concat(...items)`      | Flatten one level of arrays; new array |

**Search**

| Method                        | Notes                                 |
| ----------------------------- | ------------------------------------- |
| `includes(v, from?)`          | SameValueZero (finds `NaN`)           |
| `indexOf` / `lastIndexOf`     | Strict equality; no `NaN`             |
| `find` / `findLast`           | First/last element matching predicate |
| `findIndex` / `findLastIndex` | Index or `-1`                         |
| `some` / `every`              | Any / all pass predicate              |

**Iterate / transform / convert**

| Method                         | Notes                                |
| ------------------------------ | ------------------------------------ |
| `forEach(fn)`                  | Side effects; ignores return         |
| `map` / `filter`               | Transform / keep                     |
| `flat(depth?)` / `flatMap(fn)` | Flatten; map then flatten 1          |
| `reduce` / `reduceRight`       | Fold L→R / R→L                       |
| `keys` / `values` / `entries`  | Index / value / pair iterators       |
| `join(sep?)`                   | String; default `","`                |
| `Object.groupBy(arr, fn)`      | Group into object of arrays (ES2024) |

```js
const a = Array.from({ length: 3 }, (_, i) => i + 1); // [1, 2, 3]
const last = a.at(-1); // 3
```

## 💡 Examples [#-examples]

```js
const nums = [3, 1, 4, 1, 5];

const sorted = nums.toSorted((x, y) => x - y);
const replaced = nums.with(2, 99); // [3, 1, 99, 1, 5]
const unique = [...new Set(nums)];

function chunk(arr, size) {
  const out = [];
  for (let i = 0; i < arr.length; i += size) {
    out.push(arr.slice(i, i + size));
  }
  return out;
}

const people = [
  { name: "Ada", role: "eng" },
  { name: "Alan", role: "eng" },
  { name: "Grace", role: "ops" },
];
const byRole = Object.groupBy(people, (p) => p.role);

const nested = [[1, 2], [3], [4, 5]];
console.log(nested.flat()); // [1, 2, 3, 4, 5]

const freq = nums.reduce((m, n) => {
  m.set(n, (m.get(n) ?? 0) + 1);
  return m;
}, new Map());

const [head, ...tail] = nums;
const copy = [...nums, 9];
```

```js
const sparse = [];
sparse[2] = "x";
console.log(sparse.length); // 3

const chars = Array.from("hi"); // ["h", "i"]

// Stable partition
const evens = nums.filter((n) => n % 2 === 0);
const odds = nums.filter((n) => n % 2 !== 0);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Default `sort()` uses string order — always pass `(a, b) => a - b` for numbers.
* Prefer `toSorted` / `with` when you must not mutate shared arrays.
* `delete arr[i]` leaves a hole; use `splice` or `toSpliced`.
* `includes` uses SameValueZero (finds `NaN`); `indexOf` does not.
* Spreading huge arrays can hit call-stack / memory limits.

## 🔗 Related [#-related]

* [iteration.md](/docs/javascript/iteration) — looping patterns
* [for\_of.md](/docs/javascript/for-of) — for...of
* [iterator.md](/docs/javascript/iterator) — iterable protocol
* [map.md](/docs/javascript/map) — Map collections
* [set.md](/docs/javascript/set) — unique values
* [objects.md](/docs/javascript/objects) — Object.groupBy
* [json.md](/docs/javascript/json) — serialize arrays


---

# Arrow functions (/docs/javascript/arrow-functions)



# Arrow functions [#arrow-functions]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Arrow functions (`=>`) are compact function expressions — JS’s common “lambda” style for callbacks. They differ from `function` in `this` binding, `arguments`, constructability, and prototype. Prefer arrows for short callbacks; use `function` when you need dynamic `this` or a method on a prototype.

## 🔧 Core concepts [#-core-concepts]

* **Syntax**: `(a, b) => expr` or `(a, b) => \{ statements; return x; \}`.
* **Implicit return**: single expression body returns that value; object literals need `( \{ … \} )`.
* **Lexical `this`**: inherits `this` from the enclosing scope (no own `this`).
* **No `arguments` object**: use rest params `(...args) =>`.
* **Not constructors**: cannot `new` an arrow; no `prototype` property.
* **Callbacks**: ideal for `map` / `filter` / `then` / event handlers that should keep outer `this`.

## 💡 Examples [#-examples]

```js
const double = (n) => n * 2;
const add = (a, b) => a + b;

const nums = [1, 2, 3];
nums.map((n) => n * 2);
nums.filter((n) => n > 1);

// Block body
const sum = (arr) => {
  let t = 0;
  for (const n of arr) t += n;
  return t;
};

// Return object literal
const toPair = (k, v) => ({ [k]: v });

// Lexical this
class Timer {
  delay = 100;
  start() {
    setTimeout(() => {
      console.log(this.delay); // Timer instance
    }, this.delay);
  }
}

// vs function — own this (often wrong in callbacks)
setTimeout(function () {
  // this is not the Timer
}, 0);

// Rest instead of arguments
const max = (...xs) => Math.max(...xs);
```

```js
// Ascending sort comparator
[3, 1, 2].sort((a, b) => a - b);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Object methods as arrows on the prototype lose per-instance `this` patterns you may want; class fields as arrows are fine but not shared on the prototype.
* Implicit return of `\{\}` is a block, not an object — wrap in parentheses.
* Cannot be used as constructors or with `yield` as generators.
* `this` inside an arrow in a `function` callback still follows the outer scope — know which scope you mean.
* Longer logic is often clearer as a named `function` declaration.

## 🔗 Related [#-related]

* [Functions](/docs/javascript/functions) — declarations, expressions, params
* [this keyword](/docs/javascript/this-keyword) — `this` binding rules
* [Closures](/docs/javascript/closures) — lexical scope
* [Async](/docs/javascript/async) — async arrows `async () => \{\}`
* [Arrays](/docs/javascript/arrays) — `map` / `filter` / `reduce` callbacks


---

# Async / Await (/docs/javascript/async)



# Async / Await [#async--await]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`async` functions always return a Promise. `await` pauses the function until a thenable settles, then resumes with the value or throws the rejection. Prefer `async`/`await` for sequential flow; use `Promise.all` (and friends) for concurrency.

## 🔧 Core concepts [#-core-concepts]

* **`async function` / `async () => \{\}`**: return value is wrapped in `Promise.resolve`.
* **`await expr`**: only inside `async` functions or top-level modules.
* **Errors**: rejected promises become thrown exceptions at `await`.
* **Concurrency**: start promises first, then `await` them together.
* **Top-level await**: allowed in ES modules (and some bundler targets).

```js
async function load() {
  const res = await fetch("/api/user");
  if (!res.ok) throw new Error(res.statusText);
  return res.json();
}
```

## 💡 Examples [#-examples]

```js
// Sequential vs parallel
async function sequential(ids) {
  const out = [];
  for (const id of ids) {
    out.push(await fetch(`/u/${id}`).then((r) => r.json()));
  }
  return out;
}

async function parallel(ids) {
  return Promise.all(
    ids.map((id) => fetch(`/u/${id}`).then((r) => r.json())),
  );
}

// try/catch around await
async function safe() {
  try {
    return await load();
  } catch (err) {
    console.error(err);
    return null;
  }
}

// Await multiple
const [a, b] = await Promise.all([fetchA(), fetchB()]);

// allSettled for partial success
const results = await Promise.allSettled([p1, p2, p3]);
for (const r of results) {
  if (r.status === "fulfilled") console.log(r.value);
  else console.warn(r.reason);
}

// Async iteration
async function* pages(url) {
  let next = url;
  while (next) {
    const data = await fetch(next).then((r) => r.json());
    yield data.items;
    next = data.next;
  }
}

for await (const batch of pages("/api?page=1")) {
  console.log(batch.length);
}
```

```js
// Don't forget to return / await inside map
const bad = ids.map(async (id) => await work(id)); // Promise[]
const good = await Promise.all(ids.map((id) => work(id)));

// Microtask timing
async function order() {
  console.log("1");
  await Promise.resolve();
  console.log("3");
}
order();
console.log("2"); // 1, 2, 3
```

## ⚠️ Pitfalls [#️-pitfalls]

* `await` in a loop serializes work — often unintentional.
* Floating promises: always `await`, `return`, or `.catch()` async calls.
* `async` callbacks in `forEach` do not wait — use `for...of` or `Promise.all`.
* Catching with empty `catch` hides AbortError and network failures.
* Mixing `.then` chains with `await` is fine, but keep one style per function.

## 🔗 Related [#-related]

* [promise.md](/docs/javascript/promise) — Promise API
* [fetch.md](/docs/javascript/fetch) — HTTP requests
* [error.md](/docs/javascript/error) — try/catch patterns
* [iteration.md](/docs/javascript/iteration) — for await...of
* [for\_of.md](/docs/javascript/for-of) — sync iteration
* [api.md](/docs/javascript/api) — AbortController


---

# BigInt (/docs/javascript/bigint)



# BigInt [#bigint]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`BigInt` represents arbitrary-precision integers. Use when values exceed `Number.MAX_SAFE_INTEGER` (±2⁵³−1), such as IDs, cryptography sizes, or exact integer math. BigInts cannot mix with Numbers in arithmetic without explicit conversion.

## 🔧 Core concepts [#-core-concepts]

* **Literals**: `10n`, `-1n`.
* **Construct**: `BigInt(10)`, `BigInt("9007199254740993")`.
* **Ops**: `+ - * / % **` and bitwise on BigInts only (`/` truncates toward zero).
* **Compare**: `&lt; > &lt;= >=` work with Numbers; `===` does not coerce.
* **Typed arrays**: `BigInt64Array`, `BigUint64Array`.
* **No `Math.*`**: use explicit BigInt helpers.

```js
const huge = 9007199254740993n;
huge + 1n; // 9007199254740994n
```

## 💡 Examples [#-examples]

```js
Number.MAX_SAFE_INTEGER; // 9007199254740991
9007199254740993; // loses precision as Number
9007199254740993n; // exact

// Conversion
BigInt(42); // 42n
Number(42n); // 42 — may lose precision for large values
42n === 42; // false
42n == 42; // true (avoid ==)

// Arithmetic
(2n ** 10n); // 1024n
10n / 3n; // 3n (truncates)

// Mixing requires cast
const n = 5;
// 5n + n; // TypeError
5n + BigInt(n); // 10n

// Comparisons
1n < 2; // true
0n === 0; // false

// JSON — not supported natively
JSON.stringify({ id: 1n }); // throws
// serialize as string:
JSON.stringify({ id: 1n.toString() });

// Typed array
const buf = new BigInt64Array([1n, -2n]);
```

```js
function fib(n) {
  let a = 0n,
    b = 1n;
  for (let i = 0; i < n; i++) [a, b] = [b, a + b];
  return a;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Mixing `BigInt` and `Number` in `+`/`*` throws `TypeError`.
* `Math.max(1n, 2n)` throws — no Math support.
* Division truncates; there is no BigInt float.
* `JSON.stringify` cannot serialize BigInt — convert to string/number carefully.
* Unary `+bigint` is invalid; use `Number(bigint)` or comparisons.

## 🔗 Related [#-related]

* [number.md](/docs/javascript/number) — IEEE floats & safe integers
* [typed\_arrays.md](/docs/javascript/typed-arrays) — BigInt64Array
* [json.md](/docs/javascript/json) — serialization
* [equality.md](/docs/javascript/equality) — == vs ===
* [type\_coercion.md](/docs/javascript/type-coercion) — conversions


---

# Boolean (/docs/javascript/boolean)



# Boolean [#boolean]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

Booleans are `true` / `false`. Many values coerce via ToBoolean in conditionals. Prefer explicit checks over truthiness when `0`, `""`, or `null` are valid data.

## 🔧 Core concepts [#-core-concepts]

* **Literals**: `true`, `false`.
* **`Boolean(x)` / `!!x`**: convert with ToBoolean.
* **Falsy**: `false`, `0`, `-0`, `0n`, `""`, `null`, `undefined`, `NaN`.
* **Truthy**: everything else (including `[]`, `\{\}`, `"0"`).
* **Logical ops**: `&&`, `||`, `??` (nullish), `!`.
* **Comparisons**: `===` / `!==` preferred over `==` / `!=`.

```js
Boolean(0); // false
Boolean([]); // true
!!"hi"; // true
```

## 💡 Examples [#-examples]

```js
// Nullish vs OR
const port = settings.port ?? 3000; // only null/undefined
const title = name || "Guest"; // also replaces ""

// Short-circuit
user && user.profile && user.profile.id;
user?.profile?.id; // optional chaining

// Guards
function assert(cond, msg) {
  if (!cond) throw new Error(msg);
}

// Explicit empty checks
function hasText(s) {
  return typeof s === "string" && s.trim().length > 0;
}

// Toggle
let on = false;
on = !on;

// Boolean object trap
const boxed = new Boolean(false);
if (boxed) {
  // runs — object is truthy!
}
```

```js
// Filter truthy
const values = [0, 1, "", "a", null, undefined, NaN, false, true];
const truthy = values.filter(Boolean); // [1, "a", true]

// Predicate helpers
const isNil = (v) => v == null; // null or undefined
const isPresent = (v) => v != null;
```

## ⚠️ Pitfalls [#️-pitfalls]

* `new Boolean(false)` is an object and is truthy — never use Boolean wrappers.
* `==` coerces: `false == 0`, `"" == 0` — use `===`.
* Empty arrays/objects are truthy — check `.length` or `Object.keys`.
* `??` only skips `null`/`undefined`; `||` also skips other falsy values.
* Document APIs that return `0` or `""` so callers do not treat them as missing.

## 🔗 Related [#-related]

* [number.md](/docs/javascript/number) — numeric falsy values
* [strings.md](/docs/javascript/strings) — empty strings
* [objects.md](/docs/javascript/objects) — nullish patterns
* [switch\_case.md](/docs/javascript/switch-case) — branching
* [error.md](/docs/javascript/error) — assertions


---

# Buffer (/docs/javascript/buffer)



# Buffer [#buffer]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

In Node.js, `Buffer` is a fixed-length sequence of bytes (Uint8Array subclass). Use it for binary I/O, encodings, and crypto. Prefer `Buffer.from` / `Buffer.alloc` over the deprecated `new Buffer()`.

```js
import { Buffer } from "node:buffer";
```

## 🔧 Core concepts [#-core-concepts]

* **`Buffer.from(data, encoding?)`**: from string, array, ArrayBuffer, or another Buffer.
* **`Buffer.alloc(size, fill?, encoding?)`**: zero-filled (safe) allocation.
* **`Buffer.allocUnsafe(size)`**: faster, may contain old memory — overwrite before use.
* **Encodings**: `'utf8'` (default for many APIs), `'utf16le'`, `'base64'`, `'base64url'`, `'hex'`, `'ascii'`, `'latin1'`.
* **`buf.toString(encoding?)`**: bytes → string.
* **`buf.length`**: byte length, not string character count for multi-byte UTF-8.
* **Slice vs subarray**: `subarray` views the same memory; mutating affects the parent.

## 💡 Examples [#-examples]

```js
const a = Buffer.from("hello", "utf8");
const b = Buffer.from([0x68, 0x69]); // 'hi'
const z = Buffer.alloc(8); // 8 zero bytes

console.log(a.toString("utf8")); // 'hello'
console.log(a.toString("hex")); // '68656c6c6f'
console.log(Buffer.from("6869", "hex").toString()); // 'hi'

const b64 = Buffer.from("hi").toString("base64");
Buffer.from(b64, "base64").toString(); // 'hi'

// Concat
const all = Buffer.concat([a, b]);

// Compare / copy
Buffer.compare(a, b);
a.copy(Buffer.alloc(a.length));

// Binary file
import { readFile } from "node:fs/promises";
const buf = await readFile("image.png"); // Buffer
```

```js
// UTF-8 byte length ≠ string length
const s = "é";
[...s].length; // 1
Buffer.byteLength(s, "utf8"); // 2
```

## ⚠️ Pitfalls [#️-pitfalls]

* `allocUnsafe` can leak old data if not filled — prefer `alloc` unless profiling demands otherwise.
* Truncating multi-byte UTF-8 mid-character corrupts strings — decode carefully when slicing.
* `buf.slice` is deprecated legacy alias; use `subarray` and remember shared memory.
* Mixing encodings (e.g. treat base64 as utf8) produces garbage.
* Large buffers: stream instead of loading entire files when possible.

## 🔗 Related [#-related]

* [fs](/docs/javascript/fs) — readFile returns Buffer by default
* [Typed arrays](/docs/javascript/typed-arrays) — Uint8Array / ArrayBuffer
* [Crypto](/docs/javascript/crypto-node) — hashes over Buffers
* [Stream](/docs/javascript/stream) — chunked Buffers
* [encode](/docs/javascript/encode) — URL/text encoding related concepts


---

# child_process (/docs/javascript/child-process)



# child\_process [#child_process]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Node.js `node:child_process&#x60; runs external programs. Prefer &#x2A;*`spawn`*&#x2A; / &#x2A;*`execFile`** with argument arrays over shell `exec` when you control the command. Shell mode invites injection if user input is interpolated.

```js
import { spawn, execFile, exec } from "node:child_process";
```

## 🔧 Core concepts [#-core-concepts]

* **`spawn(command, args[], options?)`**: streams stdio; best for long-running or large output.
* **`execFile(file, args[], options?, cb)`**: runs executable directly (no shell); buffered stdout/stderr.
* **`exec(command, options?, cb)`**: runs via shell — convenient, riskier.
* **Promises**: `import \{ spawn \} from "node:child_process"` + manual wrappers, or `promisify(execFile)`.
* **Options**: `cwd`, `env`, `timeout`, `maxBuffer`, `stdio` (`'pipe' | 'inherit' | 'ignore'`).
* **Exit**: listen for `close` / `exit`; check `code` and `signal`.

## 💡 Examples [#-examples]

```js
import { spawn, execFile } from "node:child_process";
import { promisify } from "node:util";

const execFileAsync = promisify(execFile);

// Safe: args array, no shell
const { stdout } = await execFileAsync("node", ["-v"]);
console.log(stdout.trim());

const child = spawn("node", ["script.js", "--port", "9000"], {
  stdio: "inherit",
  cwd: process.cwd(),
  env: { ...process.env, NODE_ENV: "development" },
});

child.on("close", (code) => {
  console.log("exit", code);
});

// Capture streamed output
const p = spawn("git", ["status", "--porcelain"]);
let out = "";
p.stdout.setEncoding("utf8");
p.stdout.on("data", (chunk) => {
  out += chunk;
});
await new Promise((resolve, reject) => {
  p.on("error", reject);
  p.on("close", (code) => (code === 0 ? resolve() : reject(new Error(`code ${code}`))));
});
```

```js
// Avoid: exec with untrusted input
// exec(`ls ${userPath}`); // injection risk
```

## ⚠️ Pitfalls [#️-pitfalls]

* **`exec` / `execSync` shell injection**: never concatenate untrusted strings into the command line.
* **`maxBuffer`**: `exec`/`execFile` throw if output exceeds limit (default \~1MB) — use `spawn` for big output.
* Windows: `.cmd` / `.bat` often need `shell: true` or `exec`; prefer explicit `.exe` when possible.
* Forgotten listeners / open stdio can keep the parent process alive.
* `spawn` does not reject on non-zero exit by default — check `code` yourself.

## 🔗 Related [#-related]

* [process](/docs/javascript/process) — env, cwd, exit codes
* [Stream](/docs/javascript/stream) — child stdio streams
* [Events](/docs/javascript/events-node) — `close` / `error` events
* [util](/docs/javascript/util) — `promisify(execFile)`
* [Path](/docs/javascript/path) — resolve executable paths


---

# Closures (/docs/javascript/closures)



# Closures [#closures]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

A closure is a function plus the lexical environment where it was created. Inner functions keep access to outer variables even after the outer function has returned. Closures power private state, factories, event handlers, and partial application.

## 🔧 Core concepts [#-core-concepts]

* **Lexical scope**: nested functions see bindings from enclosing scopes.
* **Lifetime**: each call to the outer function creates a fresh environment.
* **Mutable capture**: closed-over `let`/`const`/`var` bindings stay live — later mutations are visible.
* **Module pattern**: IIFE or ES modules expose a public API while hiding internals.
* **Factory**: return functions that share private state.

```js
function makeCounter() {
  let n = 0;
  return () => ++n;
}
const c = makeCounter();
c(); // 1
c(); // 2
```

## 💡 Examples [#-examples]

```js
// Private state
function createBank(initial = 0) {
  let balance = initial;
  return {
    deposit(amount) {
      balance += amount;
      return balance;
    },
    getBalance() {
      return balance;
    },
  };
}

// Partial application
function multiply(a) {
  return (b) => a * b;
}
const triple = multiply(3);
triple(4); // 12

// Event handler captures element/id
function bindOnce(el, type, handler) {
  const wrapped = (e) => {
    el.removeEventListener(type, wrapped);
    handler(e);
  };
  el.addEventListener(type, wrapped);
}

// Loop pitfall fixed with let / factory
const buttons = [];
for (let i = 0; i < 3; i++) {
  buttons.push(() => i);
}
buttons[0](); // 0 — each iteration has its own i

// Memoization via closure
function memoize(fn) {
  const cache = new Map();
  return (key) => {
    if (cache.has(key)) return cache.get(key);
    const value = fn(key);
    cache.set(key, value);
    return value;
  };
}
```

```js
// Module-like IIFE
const logger = (() => {
  const levels = ["debug", "info", "warn", "error"];
  return {
    log(level, msg) {
      if (levels.includes(level)) console[level]?.(msg);
    },
  };
})();
```

## ⚠️ Pitfalls [#️-pitfalls]

* Accidental retention: closures keep references alive and can delay GC (DOM nodes, large arrays).
* `var` in loops shared one binding across iterations — use `let` or a factory.
* Returning a method that uses `this` from a closure may lose `this` when detached — bind or use arrows carefully.
* Closures over loop indices in `var` + async callbacks is a classic bug.

## 🔗 Related [#-related]

* [functions.md](/docs/javascript/functions) — function forms
* [this\_keyword.md](/docs/javascript/this-keyword) — `this` vs lexical capture
* [modules\_commonjs.md](/docs/javascript/modules-commonjs) — module scope
* [oop.md](/docs/javascript/oop) — private fields alternative
* [event\_loop.md](/docs/javascript/event-loop) — async + closures


---

# Comments (/docs/javascript/comments)



# Comments [#comments]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Comments document intent for humans. Engines ignore them. JavaScript supports single-line `//` and multi-line `/* */` comments. JSDoc-style blocks are a convention for documenting APIs.

## 🔧 Core concepts [#-core-concepts]

| Form        | Syntax       | Use                                   |
| ----------- | ------------ | ------------------------------------- |
| Single-line | `// note`    | Most everyday notes                   |
| Multi-line  | `/* ... */`  | Longer notes / temporary disable      |
| JSDoc       | `/** ... */` | Document functions/types for tooling  |
| TODO        | `// TODO:`   | Mark follow-ups (don’t leave forever) |

Comments do not replace clear names and small functions.

## 💡 Examples [#-examples]

**Single-line and inline:**

```js
// Convert Celsius to Fahrenheit
const c = 20;
const f = c * 9 / 5 + 32; // standard formula
console.log(f);
```

**Multi-line:**

```js
/*
  Demo script: comments + console output.
  Safe to delete when you understand it.
*/
console.log("ok");
```

**JSDoc-style:**

```js
/**
 * Add two numbers.
 * @param {number} a
 * @param {number} b
 * @returns {number}
 */
function add(a, b) {
  return a + b;
}

console.log(add(2, 3));
```

**Comment out an experiment:**

```js
// const legacy = oldApi();
const value = newApi();
console.log(value);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Nested `/* */` is not allowed — the first `*/` ends the comment.
* `//` inside a string is not a comment: `"http://example.com"` is fine.
* Huge blocks of commented-out code belong in Git history, not the file.
* Misleading comments are worse than none — update them when code changes.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/javascript/getting-started)
* [hello\_world.md](/docs/javascript/hello-world)
* [variables\_let\_const.md](/docs/javascript/variables-let-const)
* [typeof\_basics.md](/docs/javascript/typeof-basics)


---

# Conditionals (/docs/javascript/conditionals)



# Conditionals [#conditionals]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Conditionals branch control flow with `if` / `else if` / `else`, `switch`, and short-circuit logic. Prefer clear boolean expressions, early returns, and exhaustive switches for unions. Truthiness rules matter — know what counts as falsy.

## 🔧 Core concepts [#-core-concepts]

* **Falsy**: `false`, `0`, `-0`, `0n`, `""`, `null`, `undefined`, `NaN`.
* **Truthy**: everything else (including `[]`, `\{\}`, `"0"`).
* **`if (expr)`**: coerces with ToBoolean.
* **`else if` / `else`**: chained alternatives.
* **`switch (x)`**: strict equality (`===`) match; remember `break`.
* **Guards**: early `return` / `throw` to flatten nesting.

```js
if (user?.isAdmin) {
  allow();
} else if (user) {
  deny();
} else {
  login();
}
```

## 💡 Examples [#-examples]

```js
// Early return style
function canEdit(doc, user) {
  if (!user) return false;
  if (doc.locked) return false;
  return doc.ownerId === user.id || user.role === "admin";
}

// switch with fall-through (intentional)
switch (code) {
  case 200:
  case 201:
    return "ok";
  case 404:
    return "missing";
  default:
    return "error";
}

// switch (true) pattern
switch (true) {
  case score >= 90:
    return "A";
  case score >= 80:
    return "B";
  default:
    return "C";
}

// Short-circuit
isReady && start();
value || fallback; // prefer ?? for nullish-only
exists ? use(exists) : create();

// Numeric range
if (n >= 1 && n <= 10) {
  /* ... */
}
```

```js
// Nullish check without truthiness
if (count != null) {
  // allows 0
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `if (arr)` is always true for empty arrays — check `arr.length`.
* Assignment in condition `if (x = y)` is legal and often a bug — use `===`.
* `switch` without `break` falls through — use `break` or `return`.
* `switch` uses `===` — no coercion between `"1"` and `1`.
* Deep nesting hurts readability — extract functions / use lookup maps.

## 🔗 Related [#-related]

* [ternary.md](/docs/javascript/ternary) — conditional expressions
* [boolean.md](/docs/javascript/boolean) — booleans
* [equality.md](/docs/javascript/equality) — === vs ==
* [switch\_case.md](/docs/javascript/switch-case) — switch deep dive
* [nullish\_coalescing.md](/docs/javascript/nullish-coalescing) — defaults


---

# Console (/docs/javascript/console)



# Console [#console]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`console` is the standard debugging surface in browsers and Node. Beyond `log`, use levels, grouping, timing, and tabular output. Prefer structured messages over string concatenation.

## 🔧 Core concepts [#-core-concepts]

* **Levels**: `debug`, `log`, `info`, `warn`, `error` (filterable in DevTools).
* **Format**: `%s`, `%d`, `%o`, `%c` (CSS in browsers).
* **Groups**: `group` / `groupCollapsed` / `groupEnd`.
* **Timing**: `time` / `timeLog` / `timeEnd`.
* **Tables**: `console.table(arrayOrObject)`.
* **Assertions**: `console.assert(cond, ...msg)` logs only when falsy.
* **Counts**: `count` / `countReset`.
* **Traces**: `console.trace()` prints a stack.

```js
console.log("user=%s id=%d", "Ada", 42);
console.warn("deprecated");
console.error(new Error("fail"));
```

## 💡 Examples [#-examples]

```js
const users = [
  { id: 1, name: "Ada" },
  { id: 2, name: "Alan" },
];
console.table(users);

console.group("request");
console.log("method", "GET");
console.log("path", "/api");
console.groupEnd();

console.time("work");
await doWork();
console.timeEnd("work");

console.count("hit");
console.count("hit");
console.countReset("hit");

console.assert(users.length > 0, "expected users");

// Styled (browser)
console.log("%cOK", "color: green; font-weight: bold");

// Inspect depth (Node)
console.dir(users[0], { depth: null });

// Clear
// console.clear();
```

```js
// Debug-only helper
const debug = (...args) => {
  if (import.meta.env?.DEV ?? process.env.NODE_ENV !== "production") {
    console.debug(...args);
  }
};

debug("payload", { ok: true });
```

## ⚠️ Pitfalls [#️-pitfalls]

* Logging live objects shows later mutations in some DevTools — log clones or primitives when needed.
* `console.log` in hot paths hurts performance; gate behind flags.
* Stringifying secrets into logs is a security risk — redact tokens.
* `assert` does not throw; use real assertions for control flow.
* Node and browsers differ slightly (`dir`, `%c` support).

## 🔗 Related [#-related]

* [error.md](/docs/javascript/error) — Error objects and stacks
* [json.md](/docs/javascript/json) — pretty-print data
* [api.md](/docs/javascript/api) — runtime globals
* [objects.md](/docs/javascript/objects) — inspecting structures


---

# Crypto (/docs/javascript/crypto-node)



# Crypto [#crypto]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Node.js `node:crypto` provides hashing, HMAC, random bytes, UUIDs, and more (ciphers, key derivation). Prefer the built-in module over ad-hoc hashing. For passwords use a dedicated KDF (`scrypt`, `pbkdf2`, or `argon2` via libs) — not raw `createHash`.

```js
import crypto from "node:crypto";
```

## 🔧 Core concepts [#-core-concepts]

* **`createHash(algo)`**: one-way digest (`sha256`, `sha512`, `md5`…). Chain `.update().digest()`.
* **`randomUUID()`**: RFC 4122 v4 UUID string (cryptographically strong).
* **`randomBytes(n)`**: `n` cryptographically strong random bytes (`Buffer`); sync or callback/promise forms.
* **`createHmac(algo, key)`**: keyed hash for integrity with a secret.
* **Timing-safe compare**: `timingSafeEqual(a, b)` for secrets/hashes (same length required).

## 💡 Examples [#-examples]

```js
import crypto from "node:crypto";

const hash = crypto.createHash("sha256").update("hello", "utf8").digest("hex");

const id = crypto.randomUUID(); // '3b9f…'

const buf = crypto.randomBytes(16);
const token = buf.toString("hex");

const hmac = crypto
  .createHmac("sha256", process.env.SECRET ?? "dev")
  .update("payload")
  .digest("hex");

// Promise API (Node 15+)
import { randomBytes, randomUUID } from "node:crypto";
const bytes = await randomBytes(32);

function sha256FileBuffer(buf) {
  return crypto.createHash("sha256").update(buf).digest("hex");
}

// Compare digests safely
const a = Buffer.from(hash, "hex");
const b = Buffer.from(hash, "hex");
crypto.timingSafeEqual(a, b); // true
```

```js
// Password hashing sketch — prefer scrypt
const salt = crypto.randomBytes(16);
const key = crypto.scryptSync("password", salt, 64);
```

## ⚠️ Pitfalls [#️-pitfalls]

* `md5` / `sha1` are broken for security — use only for checksums if required.
* Never store passwords as plain `sha256(password)`; use salted slow KDFs.
* `timingSafeEqual` throws if lengths differ — check length first or pad carefully.
* `Math.random()` is not crypto-safe; use `randomBytes` / `randomUUID`.
* Streaming large inputs: call `.update()` multiple times, then `.digest()` once.

## 🔗 Related [#-related]

* [Buffer](/docs/javascript/buffer) — digests and random bytes as Buffers
* [fs](/docs/javascript/fs) — hash file contents
* [process](/docs/javascript/process) — secrets via `process.env`
* [Stream](/docs/javascript/stream) — hash while piping
* [encode](/docs/javascript/encode) — encoding helpers adjacent to hex/base64


---

# CSV (/docs/javascript/csv)



# CSV [#csv]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CSV is comma-separated text (RFC 4180–style). JavaScript has no built-in CSV parser. For simple rows you can split carefully; for real data use a library such as **Papa Parse** (browser/Node) or **csv-parse** / **csv-stringify** (Node streams).

## 🔧 Core concepts [#-core-concepts]

* **Rows / fields**: lines of records; fields separated by `,` (or `;`, `\t`).
* **Quoting**: fields with commas/newlines wrap in `"`; `""` escapes a quote.
* **Header row**: optional first line of column names.
* **Manual parse**: fine for trusted, simple files without embedded commas.
* **Libraries**: Papa Parse (`Papa.parse` / `Papa.unparse`); Node `csv-parse` + `csv-stringify`.

## 💡 Examples [#-examples]

```js
// Manual — only if no commas inside fields
function parseSimpleCsv(text) {
  return text
    .trim()
    .split(/\r?\n/)
    .map((line) => line.split(","));
}

function toSimpleCsv(rows) {
  return rows.map((r) => r.join(",")).join("\n");
}

const rows = parseSimpleCsv("name,age\nAda,36\n");
```

```js
// Escape a field for RFC-ish output
function csvField(value) {
  const s = String(value ?? "");
  if (/[",\n\r]/.test(s)) return `"${s.replaceAll('"', '""')}"`;
  return s;
}

function rowsToCsv(rows) {
  return rows.map((row) => row.map(csvField).join(",")).join("\n");
}
```

```js
// Papa Parse (npm: papaparse)
import Papa from "papaparse";

const parsed = Papa.parse(csvText, { header: true, skipEmptyLines: true });
// parsed.data → array of objects
const out = Papa.unparse(parsed.data);
```

```js
// Node csv-parse (npm: csv-parse)
import { parse } from "csv-parse/sync";
import { readFile } from "node:fs/promises";

const input = await readFile("data.csv", "utf8");
const records = parse(input, { columns: true, skip_empty_lines: true });
```

## ⚠️ Pitfalls [#️-pitfalls]

* Naïve `split(",")` breaks on quoted commas and newlines inside fields.
* Locale exports may use `;` as separator — do not assume `,`.
* Excel often expects UTF-8 BOM for Unicode; add `\uFEFF` when needed.
* Large files: prefer streaming parsers (`csv-parse` stream API), not full-string parse.
* Type coercion: CSV is all strings until you convert numbers/dates yourself.

## 🔗 Related [#-related]

* [JSON](/docs/javascript/json) — structured alternative to CSV
* [fs](/docs/javascript/fs) — read/write CSV files in Node
* [Strings](/docs/javascript/strings) — split / replace helpers
* [Async](/docs/javascript/async) — async file + parse flows
* [fetch](/docs/javascript/fetch) — download CSV over HTTP


---

# Date (/docs/javascript/date)



# Date [#date]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`Date` represents an instant in time as milliseconds since the Unix epoch (UTC). Local getters/setters use the host timezone. Prefer ISO 8601 strings and libraries (Temporal, Luxon, dayjs) for calendars and time zones when complexity grows.

## 🔧 Core concepts [#-core-concepts]

* **Create**: `new Date()`, `new Date(ms)`, `new Date(isoString)`, `Date.UTC(...)`.
* **Epoch**: `Date.now()`, `date.getTime()`, `+date`.
* **UTC vs local**: `getUTC*` / `setUTC*` vs `get*` / `set*`.
* **Format**: `toISOString()`, `toLocaleString(locale, options)`, `Intl.DateTimeFormat`.
* **Parse**: `Date.parse(string)` — implementation-defined for non-ISO forms.

```js
const now = new Date();
const utc = Date.UTC(2026, 0, 15); // month 0-based
const fromIso = new Date("2026-07-10T08:00:00.000Z");
```

## 💡 Examples [#-examples]

```js
// Add days safely via ms
function addDays(date, days) {
  return new Date(date.getTime() + days * 86_400_000);
}

// Start of local day
function startOfLocalDay(d = new Date()) {
  const x = new Date(d);
  x.setHours(0, 0, 0, 0);
  return x;
}

// Locale format
const fmt = new Intl.DateTimeFormat("en-US", {
  dateStyle: "medium",
  timeStyle: "short",
  timeZone: "America/Los_Angeles",
});
console.log(fmt.format(new Date()));

// Relative (where supported)
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
console.log(rtf.format(-1, "day")); // yesterday

// Diff in whole days (UTC calendar-ish)
function diffDays(a, b) {
  const ms = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate())
    - Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
  return ms / 86_400_000;
}

// Valid check
function isValidDate(d) {
  return d instanceof Date && !Number.isNaN(d.getTime());
}
```

```js
// Prefer ISO for interchange
JSON.stringify({ at: new Date() }); // {"at":"2026-...Z"} via toJSON

// Manual components (months are 0–11!)
const d = new Date(2026, 6, 10); // Jul 10, 2026 local
```

## ⚠️ Pitfalls [#️-pitfalls]

* Months are **0-based** in the `Date` constructor and setters.
* `new Date("YYYY-MM-DD")` is parsed as UTC; `YYYY-MM-DDTHH:mm` may be local — prefer full ISO with `Z` or offset.
* Invalid dates have `getTime() === NaN`.
* Mutator methods mutate the instance — clone before changing shared dates.
* DST makes “add one day” via `setDate` safer than fixed hours in local math for calendar days.

## 🔗 Related [#-related]

* [number.md](/docs/javascript/number) — timestamps as numbers
* [json.md](/docs/javascript/json) — Date serialization
* [api.md](/docs/javascript/api) — Intl and runtime helpers
* [strings.md](/docs/javascript/strings) — ISO string handling
* [math.md](/docs/javascript/math) — rounding durations


---

# Destructuring (/docs/javascript/destructuring)



# Destructuring [#destructuring]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Destructuring unpacks values from arrays or properties from objects into distinct variables. It works in assignments, function parameters, and `for...of` loops. Combine with defaults, rest, and renaming for concise, safe extraction.

## 🔧 Core concepts [#-core-concepts]

* **Array**: position-based — `const [a, b] = list`.
* **Object**: name-based — `const \{ x, y \} = obj`.
* **Defaults**: `const \{ a = 1 \} = \{\}` / `const [a = 1] = []`.
* **Rename**: `const \{ name: userName \} = user`.
* **Rest**: `const [head, ...tail] = arr` / `const \{ a, ...rest \} = obj`.
* **Nested**: patterns can nest arbitrarily.
* **Params**: `function f(\{ id, ...opts \} = \{\}) \{\}`.

```js
const [first, second] = [10, 20];
const { title, year = 2020 } = { title: "Guide" };
```

## 💡 Examples [#-examples]

```js
// Swap
let a = 1,
  b = 2;
[a, b] = [b, a];

// Skip slots
const [, , third] = ["a", "b", "c"]; // "c"

// Nested object
const res = { data: { user: { id: 1, name: "Ada" } } };
const {
  data: {
    user: { name },
  },
} = res;

// Rename + default
const { width: w = 100, height: h = 100 } = { width: 80 };

// Function params
function connect({ host = "localhost", port = 5432, ssl = true } = {}) {
  return `${host}:${port} ssl=${ssl}`;
}

// Iterate Map / entries
for (const [key, value] of Object.entries({ a: 1, b: 2 })) {
  console.log(key, value);
}

// Rest object (omit keys)
const user = { id: 1, name: "Ada", password: "secret" };
const { password, ...safe } = user;

// Computed property names
const key = "score";
const { [key]: score } = { score: 99 };
```

```js
// Array from iterable
const [x, y] = new Set([1, 2, 3]); // 1, 2
```

## ⚠️ Pitfalls [#️-pitfalls]

* Destructuring `null`/`undefined` throws — guard: `const \{ a \} = obj ?? \{\}`.
* Array holes and missing props become `undefined` (then defaults apply).
* Object rest copies enumerable own properties only (shallow).
* Pattern `const \{ length \} = "hi"` works (strings are array-like) but prefer explicit APIs.
* Left-hand patterns in assignment need parentheses when starting with `\{`: `(\{ a \} = obj)`.

## 🔗 Related [#-related]

* [spread\_rest.md](/docs/javascript/spread-rest) — rest/spread siblings
* [objects.md](/docs/javascript/objects) — object shapes
* [arrays.md](/docs/javascript/arrays) — array unpacking
* [functions.md](/docs/javascript/functions) — param destructuring
* [optional\_chaining.md](/docs/javascript/optional-chaining) — safe deep access


---

# Dom (/docs/javascript/dom)



# Dom [#dom]

JavaScript notes in **Dom**.


---

# Attributes (/docs/javascript/dom/attributes)



# Attributes [#attributes]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

HTML attributes are reflected on elements as content attributes and often as IDL properties. Use `getAttribute` / `setAttribute` for the HTML attribute string; use properties (`el.id`, `el.href`) for typed live values. `data-*` maps to `dataset`.

## 🔧 Core concepts [#-core-concepts]

* **Attribute API**: `hasAttribute`, `getAttribute`, `setAttribute`, `removeAttribute`, `toggleAttribute`.
* **NamedNodeMap**: `el.attributes` — live list of `Attr` nodes.
* **Property vs attribute**: `el.value` (live) vs `getAttribute("value")` (initial HTML).
* **Boolean attributes**: presence means true (`disabled`, `checked`, `hidden`).
* **`dataset`**: `data-user-id` → `el.dataset.userId`.
* **Namespaces**: `getAttributeNS` / `setAttributeNS` for SVG/MathML.

```js
el.setAttribute("aria-label", "Close");
el.toggleAttribute("hidden", true);
```

## 💡 Examples [#-examples]

```js
const btn = document.querySelector("button");

btn.setAttribute("type", "button");
btn.getAttribute("type"); // "button"
btn.hasAttribute("disabled"); // false
btn.toggleAttribute("disabled"); // adds
btn.removeAttribute("disabled");

// data-*
el.dataset.userId = "42";
console.log(el.getAttribute("data-user-id")); // "42"
delete el.dataset.userId;

// Reflecting properties
const a = document.createElement("a");
a.href = "/docs";
a.getAttribute("href"); // "/docs" (may be absolutized for href property)

// Iterate attributes
for (const attr of el.attributes) {
  console.log(attr.name, attr.value);
}

// ARIA
el.setAttribute("role", "dialog");
el.setAttribute("aria-modal", "true");

// Boolean via property
input.disabled = true;
input.hasAttribute("disabled"); // true
```

```js
// Safe read with default
function attr(el, name, fallback = "") {
  return el.hasAttribute(name) ? el.getAttribute(name) : fallback;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `getAttribute` returns `null` when missing — not `""`.
* Changing the `value` property on inputs does not always update the content attribute the same way across browsers — know which you need.
* `dataset` values are always strings; parse numbers yourself.
* Setting `innerHTML` can wipe attributes on replaced subtrees.
* Invalid attribute names or wrong namespaces fail silently or throw in XML.

## 🔗 Related [#-related]

* [class.md](/docs/javascript/dom/class) — class attribute / classList
* [selectors.md](/docs/javascript/dom/selectors) — attribute selectors
* [content\_methods.md](/docs/javascript/dom/content-methods) — reading content
* [form.md](/docs/javascript/dom/form) — form control properties
* [create\_add\_remove.md](/docs/javascript/dom/create-add-remove) — creating elements
* [../strings.md](/docs/javascript/strings) — string values
* [../objects.md](/docs/javascript/objects) — dataset object


---

# Canvas API (/docs/javascript/dom/canvas-api)



# Canvas API [#canvas-api]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The Canvas 2D API draws shapes, text, images, and pixels onto a `<canvas>` bitmap via `getContext("2d")`. Great for charts, games, and effects. For retained-mode scene graphs prefer SVG; for 3D use WebGL. Always size the drawing buffer for DPR sharpness.

## 🔧 Core concepts [#-core-concepts]

* **Context**: `const ctx = canvas.getContext("2d", \{ alpha, desynchronized \})`.
* **Drawing buffer**: `canvas.width` / `height` (attributes) ≠ CSS size.
* **State**: `save` / `restore`, transforms, styles (`fillStyle`, `strokeStyle`, `lineWidth`).
* **Paths**: `beginPath`, `moveTo`, `lineTo`, `arc`, `rect`, `fill`, `stroke`, `clip`.
* **Images**: `drawImage`, `getImageData` / `putImageData`.
* **Text**: `font`, `fillText`, `measureText`.
* **Hit testing**: custom math or `isPointInPath`.

```js
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.fillStyle = "#3366ff";
ctx.fillRect(10, 10, 100, 60);
```

## 💡 Examples [#-examples]

```js
// HiDPI setup
function fitCanvas(canvas) {
  const rect = canvas.getBoundingClientRect();
  const dpr = devicePixelRatio || 1;
  canvas.width = Math.round(rect.width * dpr);
  canvas.height = Math.round(rect.height * dpr);
  const ctx = canvas.getContext("2d");
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
  return ctx;
}

// Path
ctx.beginPath();
ctx.arc(50, 50, 40, 0, Math.PI * 2);
ctx.fill();

// Transform
ctx.save();
ctx.translate(100, 100);
ctx.rotate(Math.PI / 4);
ctx.fillRect(-25, -25, 50, 50);
ctx.restore();

// Image
const img = new Image();
img.onload = () => ctx.drawImage(img, 0, 0, 200, 120);
img.src = "/photo.jpg";

// Pixels
const data = ctx.getImageData(0, 0, w, h);
for (let i = 0; i < data.data.length; i += 4) {
  data.data[i] = 255 - data.data[i]; // R invert
}
ctx.putImageData(data, 0, 0);

// Animation
function frame(t) {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  draw(t);
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Setting `width`/`height` resets the context state and clears the bitmap.
* CSS scaling without DPR adjustment blurs drawings.
* `getImageData` is expensive and taints canvas if cross-origin images lack CORS.
* Canvas is inaccessible by default — provide fallback text / ARIA when needed.
* Clearing with `clearRect` each frame; forgetting it leaves trails.

## 🔗 Related [#-related]

* [../Html/canvas.md](/docs/javascript/../html/canvas) — canvas element
* [../typed\_arrays.md](/docs/javascript/typed-arrays) — ImageData buffers
* [../timers.md](/docs/javascript/timers) — rAF loops
* [resize\_observer.md](/docs/javascript/dom/resize-observer) — responsive canvas
* [../performance.md](/docs/javascript/performance) — draw cost


---

# classList & CSS Classes (/docs/javascript/dom/class)



# classList & CSS Classes [#classlist--css-classes]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

`element.classList` is a live `DOMTokenList` for CSS class tokens. Prefer it over string-splicing `className`. It supports add/remove/toggle/replace and iteration.

## 🔧 Core concepts [#-core-concepts]

* **API**: `add`, `remove`, `toggle`, `contains`, `replace`, `item`, `length`.
* **`className`**: full string getter/setter (space-separated).
* **`classList.value`**: string form of the token list.
* **Toggle force**: `toggle(token, force)` — `true` adds, `false` removes.
* **SVG**: same `classList` on SVG elements in modern browsers.

```js
el.classList.add("is-open", "animate");
el.classList.toggle("is-open");
```

## 💡 Examples [#-examples]

```js
const el = document.querySelector(".panel");

el.classList.add("visible");
el.classList.remove("hidden");
el.classList.contains("visible"); // true

// Force on/off
el.classList.toggle("active", isActive);

// Replace token
el.classList.replace("theme-light", "theme-dark");

// Iterate
for (const token of el.classList) {
  console.log(token);
}

// One-shot from state object
function applyState(el, state) {
  el.classList.toggle("is-loading", state.loading);
  el.classList.toggle("is-error", state.error);
  el.classList.toggle("is-ready", state.ready);
}

// Avoid duplicates / empties — classList handles spaces & dupes
el.className = "  a   a  b "; // messy
el.classList.add("a", "b"); // clean tokens
```

```js
// Animation reflow trick
el.classList.remove("pulse");
void el.offsetWidth; // force reflow
el.classList.add("pulse");
```

```js
// Conditional multi-class from a list
function setClasses(el, tokens) {
  el.className = ""; // reset
  el.classList.add(...tokens.filter(Boolean));
}

setClasses(el, ["card", isFeatured && "card--featured", size]);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Tokens cannot contain spaces — each class is one token.
* `className` on SVG historically returned `SVGAnimatedString` — prefer `classList`.
* Toggling in tight loops can thrash layout if combined with measuring.
* Don’t store state only in classes if you need typed data — use `data-*` or JS state.
* Removing a missing class is a no-op; adding an existing class is a no-op.

## 🔗 Related [#-related]

* [attributes.md](/docs/javascript/dom/attributes) — class attribute
* [selectors.md](/docs/javascript/dom/selectors) — `.class` selectors
* [events.md](/docs/javascript/dom/events) — UI state toggles
* [content\_methods.md](/docs/javascript/dom/content-methods) — updating UI
* [position.md](/docs/javascript/dom/position) — layout reads after class changes
* [../strings.md](/docs/javascript/strings) — token strings


---

# Clipboard API (/docs/javascript/dom/clipboard-api)



# Clipboard API [#clipboard-api]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The Async Clipboard API reads and writes the system clipboard with promises: `navigator.clipboard.writeText` / `readText`, and richer `write` / `read` with `ClipboardItem`. Requires secure context and often transient user activation / permissions.

## 🔧 Core concepts [#-core-concepts]

* **Text**: `await navigator.clipboard.writeText(str)` / `readText()`.
* **Items**: `clipboard.write([new ClipboardItem(\{ [type]: blob \})])`.
* **Permissions**: `clipboard-read` / `clipboard-write` (browser-dependent).
* **Secure context**: HTTPS or localhost.
* **Fallback**: legacy `document.execCommand("copy")` with a temporary textarea (deprecated).
* **Paste events**: `paste` / `copy` / `cut` still useful for intercepting.

```js
await navigator.clipboard.writeText("Hello");
const text = await navigator.clipboard.readText();
```

## 💡 Examples [#-examples]

```js
// Copy button
btn.addEventListener("click", async () => {
  try {
    await navigator.clipboard.writeText(input.value);
    toast("Copied");
  } catch {
    toast("Clipboard blocked");
  }
});

// Copy HTML + plain text
async function copyRich(html, plain) {
  const item = new ClipboardItem({
    "text/plain": new Blob([plain], { type: "text/plain" }),
    "text/html": new Blob([html], { type: "text/html" }),
  });
  await navigator.clipboard.write([item]);
}

// Read image (where supported)
const items = await navigator.clipboard.read();
for (const item of items) {
  if (item.types.includes("image/png")) {
    const blob = await item.getType("image/png");
    img.src = URL.createObjectURL(blob);
  }
}

// Paste event
editor.addEventListener("paste", (e) => {
  const text = e.clipboardData?.getData("text/plain");
  const file = e.clipboardData?.files?.[0];
  // e.preventDefault(); custom insert
});

// Permission query
const status = await navigator.permissions.query({ name: "clipboard-read" });
```

```js
// Feature detect
if (!navigator.clipboard?.writeText) {
  /* show manual select UI */
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `readText` often requires permission + user gesture; expect failures in background tabs.
* Safari / Firefox policies differ for read — always try/catch and UX fallback.
* Don’t put secrets on the clipboard longer than needed.
* `ClipboardItem` blob MIME types must match what you write.
* Focus may be required — call from click handlers, not arbitrary timers.

## 🔗 Related [#-related]

* [events.md](/docs/javascript/dom/events) — copy/paste events
* [datatransfer.md](/docs/javascript/dom/datatransfer) — DataTransfer
* [drag\_drop.md](/docs/javascript/dom/drag-drop) — drag data
* [../encode.md](/docs/javascript/encode) — text encoding
* [form.md](/docs/javascript/dom/form) — selecting input text


---

# Content Methods (/docs/javascript/dom/content-methods)



# Content Methods [#content-methods]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

Read and write element content with `textContent`, `innerHTML`, `innerText`, and modern helpers like `insertAdjacentHTML`. Prefer `textContent` for untrusted strings; use HTML APIs only with sanitized markup.

## 🔧 Core concepts [#-core-concepts]

* **`textContent`**: all descendant text; no HTML parsing; fast and safe for plain text.
* **`innerHTML`**: get/set HTML markup; parses and replaces children.
* **`innerText`**: layout-aware visible text (triggers reflow); respects CSS.
* **`outerHTML`**: includes the element itself.
* **Adjacent**: `insertAdjacentHTML/Text/Element(position, ...)`.
* **Positions**: `beforebegin`, `afterbegin`, `beforeend`, `afterend`.

```js
el.textContent = userInput; // safe plain text
el.insertAdjacentHTML("beforeend", trustedHtml);
```

## 💡 Examples [#-examples]

```js
const box = document.querySelector("#box");

box.textContent = "Hello";
box.innerHTML = "<strong>Hello</strong>";

// Append HTML without wiping siblings' listeners on whole parent
box.insertAdjacentHTML("beforeend", "<li>Item</li>");
box.insertAdjacentText("afterbegin", "Note: ");

// Build with elements instead of HTML strings
const li = document.createElement("li");
li.textContent = item.name;
box.append(li);

// Read
const visible = box.innerText;
const all = box.textContent;

// Clear
box.replaceChildren(); // modern clear
// box.innerHTML = "";
```

```js
// Template + sanitize strategy: never assign raw user HTML
function renderComment(el, text) {
  el.textContent = "";
  const p = document.createElement("p");
  p.textContent = text;
  el.append(p);
}
```

```js
// insertAdjacentElement keeps node identity / listeners
const note = document.createElement("aside");
note.textContent = "Tip";
box.insertAdjacentElement("afterend", note);

console.log(box.outerHTML.slice(0, 40));
```

## ⚠️ Pitfalls [#️-pitfalls]

* Assigning `innerHTML` with user data is an XSS risk.
* Setting `innerHTML` destroys existing child nodes and their listeners.
* `innerText` is slower and style-dependent — prefer `textContent` for logic.
* `outerHTML` replacement can detach the element reference you hold.
* HTML parsing may normalize/fix markup unexpectedly.

## 🔗 Related [#-related]

* [create\_add\_remove.md](/docs/javascript/dom/create-add-remove) — node creation
* [mutation\_methods.md](/docs/javascript/dom/mutation-methods) — append/replace
* [attributes.md](/docs/javascript/dom/attributes) — attributes vs content
* [selectors.md](/docs/javascript/dom/selectors) — finding targets
* [../strings.md](/docs/javascript/strings) — escaping text
* [../encode.md](/docs/javascript/encode) — encoding


---

# Create, Add, Remove (/docs/javascript/dom/create-add-remove)



# Create, Add, Remove [#create-add-remove]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

Build DOM trees with `createElement`, `createTextNode`, and modern insertion methods (`append`, `prepend`, `before`, `after`, `replaceWith`, `remove`). Prefer these over legacy `parentNode.appendChild` when you can.

## 🔧 Core concepts [#-core-concepts]

* **Create**: `document.createElement(tag)`, `createElementNS`, `createTextNode`, `cloneNode(deep)`.
* **Insert**: `append`, `prepend`, `before`, `after`, `insertBefore`.
* **Replace / remove**: `replaceWith`, `replaceChildren`, `remove`, `replaceChild`.
* **DocumentFragment**: batch insert with one reflow.
* **Template**: `<template>` → `template.content.cloneNode(true)`.

```js
const el = document.createElement("button");
el.textContent = "Save";
parent.append(el);
```

## 💡 Examples [#-examples]

```js
const list = document.querySelector("#list");

const li = document.createElement("li");
li.className = "item";
li.textContent = "New item";
list.append(li);

// Multiple nodes
list.prepend(document.createTextNode("Header"), li.cloneNode(true));

// Fragment batching
const frag = document.createDocumentFragment();
for (const name of names) {
  const item = document.createElement("li");
  item.textContent = name;
  frag.append(item);
}
list.append(frag);

// Template
const tpl = document.querySelector("#row");
const row = tpl.content.cloneNode(true);
row.querySelector(".name").textContent = user.name;
list.append(row);

// Move existing node (reparent)
list.append(existingLi); // moves if already in DOM

// Remove
li.remove();
list.replaceChildren(); // clear all
```

```js
// Range createContextualFragment (HTML string → nodes)
const range = document.createRange();
const nodes = range.createContextualFragment("<span>Hi</span>");
parent.append(nodes);
```

## ⚠️ Pitfalls [#️-pitfalls]

* `appendChild` returns the node; `append` can take strings (as text) and multiple args.
* Cloning with `cloneNode(true)` does **not** copy event listeners (unless you rebind).
* Inserting a node already in the tree **moves** it — it is not copied.
* Creating thousands of nodes one-by-one without a fragment causes layout thrash.
* `innerHTML += ...` re-parses the whole subtree — avoid in loops.

## 🔗 Related [#-related]

* [mutation\_methods.md](/docs/javascript/dom/mutation-methods) — mutation details
* [content\_methods.md](/docs/javascript/dom/content-methods) — text/HTML content
* [selectors.md](/docs/javascript/dom/selectors) — locating parents
* [document\_methods.md](/docs/javascript/dom/document-methods) — document factories
* [range.md](/docs/javascript/dom/range) — Range fragments
* [../strings.md](/docs/javascript/strings) — text nodes


---

# CSSOM (/docs/javascript/dom/cssom)



# CSSOM [#cssom]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The CSS Object Model lets JS read and mutate stylesheets and computed style: `element.style`, `getComputedStyle`, `CSSStyleSheet` rules, and CSS variables. Prefer CSS classes for most UI state; use CSSOM for measured values, theming tokens, and dynamic rule injection.

## 🔧 Core concepts [#-core-concepts]

* **Inline**: `el.style.color`, `el.style.setProperty("--x", "1")`, `cssText`.
* **Computed**: `getComputedStyle(el)` — live, read-only, resolved values.
* **Sheets**: `document.styleSheets`, `sheet.cssRules`, `insertRule` / `deleteRule`.
* **Constructed stylesheets**: `new CSSStyleSheet()` + `adoptedStyleSheets` (shadow/document).
* **Variables**: `getPropertyValue("--token")`, `setProperty`, `removeProperty`.
* **OM values**: typed OM (`attributeStyleMap`) where supported.

```js
el.style.setProperty("--gap", "1rem");
const color = getComputedStyle(el).color;
```

## 💡 Examples [#-examples]

```js
// Toggle via custom property
document.documentElement.style.setProperty("--theme-bg", "#111");

// Read resolved size (px strings)
const { width, fontSize } = getComputedStyle(el);
const w = parseFloat(width);

// Avoid thrashing: batch reads/writes
const styles = els.map((el) => getComputedStyle(el).height);
els.forEach((el, i) => {
  el.style.minHeight = styles[i];
});

// Insert a rule
const sheet = document.styleSheets[0];
const i = sheet.insertRule(".flash { outline: 2px solid red; }", sheet.cssRules.length);
// sheet.deleteRule(i);

// Constructable stylesheet (components)
const sheet2 = new CSSStyleSheet();
sheet2.replaceSync(`:host { display: block; } .x { color: tomato; }`);
shadow.adoptedStyleSheets = [sheet2];

// CSS.escape for dynamic selectors
const sel = `#${CSS.escape(id)}`;
```

```js
// Feature: typed OM
el.attributeStyleMap.set("padding-top", CSS.px(8));
```

## ⚠️ Pitfalls [#️-pitfalls]

* `el.style` only sees **inline** styles — not classes; use `getComputedStyle` for final values.
* `getComputedStyle` forces layout — don’t call it in tight loops interleaved with writes.
* Cross-origin stylesheets block rule access (SecurityError).
* Shorthand reads from computed style may be empty or expanded inconsistently.
* Prefer classList for state; inline styles fight specificity and CSP.

## 🔗 Related [#-related]

* [class.md](/docs/javascript/dom/class) — classList
* [attributes.md](/docs/javascript/dom/attributes) — style attribute
* [position.md](/docs/javascript/dom/position) — layout metrics
* [resize\_observer.md](/docs/javascript/dom/resize-observer) — size changes
* [../CSS/variables.md](/docs/javascript/../css/variables) — custom properties


---

# Custom Elements (/docs/javascript/dom/custom-elements)



# Custom Elements [#custom-elements]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Custom Elements let you define new HTML tags (or upgrade builtins) with a JavaScript class. Combined with Shadow DOM and `<template>`, they form Web Components — reusable, encapsulated UI with lifecycle callbacks.

## 🔧 Core concepts [#-core-concepts]

* **Define**: `customElements.define("my-el", class extends HTMLElement \{ ... \})`.
* **Name**: must include a hyphen (`my-card`).
* **Lifecycle**: `connectedCallback`, `disconnectedCallback`, `attributeChangedCallback`, `adoptedCallback`.
* **Observed attrs**: static `observedAttributes = ["open"]`.
* **Autonomous** vs **customized built-in**: `extends: "button"` + `is="..."`.
* **Upgrade**: `customElements.whenDefined("my-el")`, `upgrade`.

```js
class HelloWorld extends HTMLElement {
  connectedCallback() {
    this.textContent = "Hello";
  }
}
customElements.define("hello-world", HelloWorld);
```

## 💡 Examples [#-examples]

```js
class FancyButton extends HTMLElement {
  static observedAttributes = ["label", "disabled"];

  constructor() {
    super();
    this.attachShadow({ mode: "open" });
    this.shadowRoot.innerHTML = `<button part="button"><slot></slot></button>`;
    this._btn = this.shadowRoot.querySelector("button");
  }

  connectedCallback() {
    this._btn.addEventListener("click", this._onClick);
  }

  disconnectedCallback() {
    this._btn.removeEventListener("click", this._onClick);
  }

  attributeChangedCallback(name, oldVal, newVal) {
    if (oldVal === newVal) return;
    if (name === "label") this._btn.textContent = newVal;
    if (name === "disabled") this._btn.disabled = newVal != null;
  }

  _onClick = () => {
    this.dispatchEvent(new CustomEvent("fancy-click", { bubbles: true }));
  };
}
customElements.define("fancy-button", FancyButton);

// Wait for definition
await customElements.whenDefined("fancy-button");
document.createElement("fancy-button");

// Customized built-in (where supported)
class ExpandingList extends HTMLUListElement {
  connectedCallback() {
    this.addEventListener("click", () => this.classList.toggle("open"));
  }
}
customElements.define("expanding-list", ExpandingList, { extends: "ul" });
// <ul is="expanding-list">
```

```js
// Reflect property ↔ attribute
get open() {
  return this.hasAttribute("open");
}
set open(v) {
  this.toggleAttribute("open", Boolean(v));
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Must call `super()` in constructors before using `this`; don’t read attributes too early if not upgraded.
* Customized built-ins lack Safari support historically — prefer autonomous elements for portability.
* `attributeChangedCallback` does not fire for property-only changes unless you reflect.
* Defining twice throws — guard or use feature detection.
* Slotted light DOM vs shadow: know where events retarget.

## 🔗 Related [#-related]

* [shadow\_dom.md](/docs/javascript/dom/shadow-dom) — encapsulation
* [../Html/template\_slot.md](/docs/javascript/../html/template-slot) — templates
* [../Html/web\_components.md](/docs/javascript/../html/web-components) — overview
* [attributes.md](/docs/javascript/dom/attributes) — attribute APIs
* [events.md](/docs/javascript/dom/events) — CustomEvent


---

# DataTransfer & Drag-and-Drop (/docs/javascript/dom/datatransfer)



# DataTransfer & Drag-and-Drop [#datatransfer--drag-and-drop]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

`DataTransfer` carries payload during drag-and-drop and clipboard operations. Set data in `dragstart`, read it in `drop`. Use `DataTransferItemList` for files and multiple MIME types.

## 🔧 Core concepts [#-core-concepts]

* **Events**: `dragstart`, `drag`, `dragenter`, `dragover`, `dragleave`, `drop`, `dragend`.
* **`event.dataTransfer`**: `setData`, `getData`, `clearData`, `types`, `files`, `items`.
* **`effectAllowed` / `dropEffect`**: copy | move | link | none.
* **`setDragImage(element, x, y)`**: custom ghost image.
* **Clipboard**: `ClipboardEvent.clipboardData` is also a `DataTransfer`.

```js
el.addEventListener("dragstart", (e) => {
  e.dataTransfer.setData("text/plain", el.id);
  e.dataTransfer.effectAllowed = "move";
});
```

## 💡 Examples [#-examples]

```js
const source = document.querySelector("#source");
const target = document.querySelector("#target");

source.draggable = true;

source.addEventListener("dragstart", (e) => {
  e.dataTransfer.setData("application/x-item-id", source.dataset.id);
  e.dataTransfer.setData("text/plain", source.textContent);
  e.dataTransfer.effectAllowed = "copyMove";
});

// Must preventDefault on dragover to allow drop
target.addEventListener("dragover", (e) => {
  e.preventDefault();
  e.dataTransfer.dropEffect = "move";
  target.classList.add("drag-over");
});

target.addEventListener("dragleave", () => {
  target.classList.remove("drag-over");
});

target.addEventListener("drop", (e) => {
  e.preventDefault();
  target.classList.remove("drag-over");
  const id = e.dataTransfer.getData("application/x-item-id");
  const node = document.querySelector(`[data-id="${CSS.escape(id)}"]`);
  if (node) target.append(node);
});

// File drop
target.addEventListener("drop", async (e) => {
  e.preventDefault();
  const files = [...e.dataTransfer.files];
  for (const file of files) {
    console.log(file.name, file.type, file.size);
  }
});
```

```js
// Clipboard paste image
editor.addEventListener("paste", (e) => {
  const items = e.clipboardData?.items;
  if (!items) return;
  for (const item of items) {
    if (item.type.startsWith("image/")) {
      const file = item.getAsFile();
      // upload / preview file
    }
  }
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Without `preventDefault` on `dragover`, `drop` will not fire.
* `getData` for custom types may be empty outside `drop` in some browsers (security).
* `files` is only populated for file drags — not for element drags.
* MIME type strings are case-sensitive conventions (`text/plain`).
* Touch devices often lack HTML5 DnD — provide click alternatives.

## 🔗 Related [#-related]

* [events.md](/docs/javascript/dom/events) — event handling
* [form.md](/docs/javascript/dom/form) — file inputs
* [attributes.md](/docs/javascript/dom/attributes) — draggable / data-\*
* [create\_add\_remove.md](/docs/javascript/dom/create-add-remove) — moving nodes
* [../api.md](/docs/javascript/api) — File / Blob APIs
* [../async.md](/docs/javascript/async) — async file reads


---

# Document Methods (/docs/javascript/dom/document-methods)



# Document Methods [#document-methods]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

`document` is the entry point to the DOM tree: querying, creating nodes, reading metadata, and listening for lifecycle events. Prefer `document` methods over legacy globals like `document.all`.

## 🔧 Core concepts [#-core-concepts]

* **Query**: `getElementById`, `querySelector`, `querySelectorAll`, `getElementsBy*`.
* **Create**: `createElement`, `createTextNode`, `createDocumentFragment`, `createRange`.
* **Adopt/import**: `importNode`, `adoptNode` across documents.
* **Metadata**: `title`, `URL`, `documentElement`, `head`, `body`, `compatMode`.
* **Ready**: `DOMContentLoaded`, `document.readyState`, `document.fonts`.
* **Visibility**: `document.visibilityState`, `visibilitychange`.

```js
document.addEventListener("DOMContentLoaded", () => {
  init(document.getElementById("app"));
});
```

## 💡 Examples [#-examples]

```js
const app = document.getElementById("app");
const first = document.querySelector(".item");
const all = document.querySelectorAll(".item"); // static NodeList

// Collections (live)
const live = document.getElementsByClassName("item");
const tags = document.getElementsByTagName("div");

// Create & insert
const el = document.createElement("section");
el.id = "panel";
document.body.append(el);

// Ready helpers
if (document.readyState === "loading") {
  document.addEventListener("DOMContentLoaded", start);
} else {
  start();
}

// Visibility pause
document.addEventListener("visibilitychange", () => {
  if (document.hidden) pause();
  else resume();
});

// Current script (classic scripts)
const current = document.currentScript;

// Open graph-ish meta
document.title = "Dashboard";
```

```js
// Wait for fonts
await document.fonts.ready;
drawText();

// CSS escape for dynamic selectors
const id = "a.b#c";
document.querySelector(`#${CSS.escape(id)}`);
```

## ⚠️ Pitfalls [#️-pitfalls]

* `getElementsBy*` collections are **live**; `querySelectorAll` is static.
* `document.write` clobbers the page after load — avoid it.
* Scripts of `type="module"` defer by default — `DOMContentLoaded` may already have fired.
* `getElementById` does not need `#`; `querySelector` does.
* Accessing `document.body` before it exists returns `null`.

## 🔗 Related [#-related]

* [selectors.md](/docs/javascript/dom/selectors) — selector engines
* [create\_add\_remove.md](/docs/javascript/dom/create-add-remove) — node factories
* [events.md](/docs/javascript/dom/events) — document listeners
* [window.md](/docs/javascript/dom/window) — window ↔ document
* [navigation.md](/docs/javascript/dom/navigation) — location / history
* [../async.md](/docs/javascript/async) — waiting for ready


---

# Drag & Drop (/docs/javascript/dom/drag-drop)



# Drag & Drop [#drag--drop]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

HTML Drag and Drop uses `draggable` elements and drag events (`dragstart`, `dragover`, `drop`, …) with `DataTransfer` payloads. Good for reordering lists and file drops. For complex apps, consider Pointer Events libraries — native DnD has quirks across browsers.

## 🔧 Core concepts [#-core-concepts]

* **Make draggable**: `draggable="true"` on elements (images/links are draggable by default).
* **Events (source)**: `dragstart`, `drag`, `dragend`.
* **Events (target)**: `dragenter`, `dragover`, `dragleave`, `drop`.
* **`dataTransfer`**: `setData`/`getData`, `effectAllowed`, `dropEffect`, `files`, `items`.
* **Must `preventDefault` on `dragover`** to allow dropping.
* **File drop**: read `e.dataTransfer.files`.

```js
el.draggable = true;
el.addEventListener("dragstart", (e) => {
  e.dataTransfer.setData("text/plain", el.id);
});
zone.addEventListener("dragover", (e) => e.preventDefault());
zone.addEventListener("drop", (e) => {
  e.preventDefault();
  const id = e.dataTransfer.getData("text/plain");
});
```

## 💡 Examples [#-examples]

```js
// Reorder list item
list.querySelectorAll("[data-id]").forEach((item) => {
  item.draggable = true;
  item.addEventListener("dragstart", (e) => {
    e.dataTransfer.setData("text/plain", item.dataset.id);
    item.classList.add("dragging");
  });
  item.addEventListener("dragend", () => item.classList.remove("dragging"));
});

list.addEventListener("dragover", (e) => {
  e.preventDefault();
  const after = getDragAfterElement(list, e.clientY);
  const dragging = list.querySelector(".dragging");
  if (!after) list.append(dragging);
  else list.insertBefore(dragging, after);
});

// File drop zone
zone.addEventListener("dragover", (e) => {
  e.preventDefault();
  zone.classList.add("over");
});
zone.addEventListener("dragleave", () => zone.classList.remove("over"));
zone.addEventListener("drop", async (e) => {
  e.preventDefault();
  zone.classList.remove("over");
  const files = [...e.dataTransfer.files];
  for (const file of files) await upload(file);
});

// Custom ghost image
e.dataTransfer.setDragImage(img, 10, 10);
e.dataTransfer.effectAllowed = "move";
```

```js
// Types
e.dataTransfer.types; // ["text/plain", "Files", ...]
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting `preventDefault` on `dragover` silently blocks `drop`.
* `getData` may be empty in `dragover` in some browsers for security — read on `drop`.
* Touch devices historically weak for HTML DnD — provide alternatives.
* Draggable text selection conflicts — manage UX carefully.
* See also Pointer Events for custom drag implementations.

## 🔗 Related [#-related]

* [datatransfer.md](/docs/javascript/dom/datatransfer) — DataTransfer deep dive
* [events.md](/docs/javascript/dom/events) — event model
* [clipboard\_api.md](/docs/javascript/dom/clipboard-api) — clipboard data
* [form.md](/docs/javascript/dom/form) — file inputs
* [../encode.md](/docs/javascript/encode) — MIME types


---

# Events (/docs/javascript/dom/events)



# Events [#events]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

DOM events notify your code about user and system actions. Register with `addEventListener`, control propagation with `stopPropagation` / `preventDefault`, and prefer delegation for dynamic lists.

## 🔧 Core concepts [#-core-concepts]

* **Listen**: `addEventListener(type, handler, options?)`, `removeEventListener` (same ref/options).
* **Options**: `\{ capture, once, passive, signal \}`.
* **Phases**: capture → target → bubble.
* **Event object**: `type`, `target`, `currentTarget`, `eventPhase`, `timeStamp`.
* **Cancel**: `preventDefault()` when `cancelable`; check `defaultPrevented`.
* **Custom**: `new CustomEvent(name, \{ detail, bubbles, cancelable \})` + `dispatchEvent`.

```js
btn.addEventListener("click", onClick, { once: true });
```

## 💡 Examples [#-examples]

```js
function onClick(e) {
  console.log(e.target, e.currentTarget);
  e.preventDefault();
}

link.addEventListener("click", onClick);
link.removeEventListener("click", onClick);

// AbortSignal unsubscribe
const ac = new AbortController();
window.addEventListener("resize", onResize, { signal: ac.signal });
ac.abort(); // removes listener

// Delegation
list.addEventListener("click", (e) => {
  const item = e.target.closest("li[data-id]");
  if (!item || !list.contains(item)) return;
  select(item.dataset.id);
});

// Keyboard
input.addEventListener("keydown", (e) => {
  if (e.key === "Enter" && !e.shiftKey) {
    e.preventDefault();
    submit();
  }
});

// Passive scroll (perf)
window.addEventListener("touchmove", onMove, { passive: true });

// Custom events
panel.addEventListener("cart:add", (e) => console.log(e.detail));
panel.dispatchEvent(
  new CustomEvent("cart:add", { detail: { id: 1 }, bubbles: true }),
);
```

```js
// Pointer events unify mouse/touch/pen
el.addEventListener("pointerdown", (e) => {
  el.setPointerCapture(e.pointerId);
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Anonymous handlers cannot be removed — keep a reference.
* Capture flag must match between add and remove.
* `passive: true` listeners cannot `preventDefault` (useful for scroll perf).
* Inline `onclick=` attributes and property handlers differ from `addEventListener` stacking.
* Forgetting delegation causes missing listeners on dynamically added nodes.

## 🔗 Related [#-related]

* [form.md](/docs/javascript/dom/form) — submit / input events
* [datatransfer.md](/docs/javascript/dom/datatransfer) — drag events
* [selectors.md](/docs/javascript/dom/selectors) — closest / matches
* [window.md](/docs/javascript/dom/window) — window-level events
* [mutation\_methods.md](/docs/javascript/dom/mutation-methods) — MutationObserver
* [../api.md](/docs/javascript/api) — AbortSignal
* [../async.md](/docs/javascript/async) — async handlers


---

# Fetch Streaming (/docs/javascript/dom/fetch-streaming)



# Fetch Streaming [#fetch-streaming]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Fetch responses expose a `ReadableStream` body for incremental processing — large files, SSE-like chunked text, and progressive JSON. Use readers, `TextDecoderStream`, and backpressure-aware transforms instead of buffering entire payloads with `res.text()` / `res.json()`.

## 🔧 Core concepts [#-core-concepts]

* **Body**: `response.body` → `ReadableStream`.
* **Read**: `const reader = body.getReader()` then `reader.read()` → `\{ value, done \}`.
* **Cancel**: `reader.cancel()` / `AbortSignal` on fetch.
* **Tee**: `body.tee()` for dual consumers.
* **Pipes**: `pipeThrough(new TextDecoderStream())`, `pipeTo(writable)`.
* **Request streams**: duplex upload where supported (`duplex: "half"`).

```js
const res = await fetch("/large.txt");
const reader = res.body.getReader();
const { value, done } = await reader.read();
```

## 💡 Examples [#-examples]

```js
// Byte loop
async function readBytes(url, signal) {
  const res = await fetch(url, { signal });
  if (!res.ok) throw new Error(res.status);
  const reader = res.body.getReader();
  const chunks = [];
  while (true) {
    const { value, done } = await reader.read();
    if (done) break;
    chunks.push(value);
  }
  return chunks;
}

// Text lines via streams
async function* lines(url) {
  const res = await fetch(url);
  const text = res.body.pipeThrough(new TextDecoderStream());
  const reader = text.getReader();
  let buf = "";
  while (true) {
    const { value, done } = await reader.read();
    if (done) break;
    buf += value;
    let idx;
    while ((idx = buf.indexOf("\n")) >= 0) {
      yield buf.slice(0, idx);
      buf = buf.slice(idx + 1);
    }
  }
  if (buf) yield buf;
}

// Progress with Content-Length
async function downloadWithProgress(url, onProgress) {
  const res = await fetch(url);
  const total = Number(res.headers.get("content-length")) || 0;
  let loaded = 0;
  const reader = res.body.getReader();
  const chunks = [];
  while (true) {
    const { value, done } = await reader.read();
    if (done) break;
    chunks.push(value);
    loaded += value.byteLength;
    onProgress(loaded, total);
  }
  return new Blob(chunks);
}

// Abort mid-stream
const c = new AbortController();
fetch("/stream", { signal: c.signal });
c.abort();
```

## ⚠️ Pitfalls [#️-pitfalls]

* Calling `res.json()` after reading `body` fails — body can be consumed once (unless teed).
* Not all servers send useful `Content-Length` (chunked) — progress may be indeterminate.
* Backpressure: don’t buffer unbounded chunks in memory.
* CORS and opaque responses limit body access.
* Upload streaming support is uneven across browsers — feature-detect.

## 🔗 Related [#-related]

* [../fetch.md](/docs/javascript/fetch) — fetch basics
* [../abort\_controller.md](/docs/javascript/abort-controller) — cancel
* [../typed\_arrays.md](/docs/javascript/typed-arrays) — Uint8Array chunks
* [../async.md](/docs/javascript/async) — async iteration
* [../encode.md](/docs/javascript/encode) — TextDecoder


---

# Focus & Blur (/docs/javascript/dom/focus-blur)



# Focus & Blur [#focus--blur]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Focus determines which element receives keyboard input. Manage it with `focus()`, `blur()`, `tabIndex`, autofocus, and focus events. Critical for accessibility, modals, and forms. Prefer moving focus intentionally; never trap keyboard users without an escape.

## 🔧 Core concepts [#-core-concepts]

* **Methods**: `el.focus(\{ preventScroll? \})`, `el.blur()`.
* **Events**: `focus`, `blur` (no bubble); `focusin`, `focusout` (bubble).
* **`document.activeElement`**: currently focused element.
* **Tab order**: DOM order + `tabindex` (`0` in order, positive avoid, `-1` programmatic only).
* **Focusable**: links, buttons, inputs, `[tabindex]`, some custom with `tabindex=0`.
* **`:focus-visible`**: keyboard-ish focus styling (CSS).

```js
input.focus();
input.addEventListener("focus", () => input.select());
```

## 💡 Examples [#-examples]

```js
// focusin delegation
form.addEventListener("focusin", (e) => {
  e.target.closest(".field")?.classList.add("focused");
});
form.addEventListener("focusout", (e) => {
  e.target.closest(".field")?.classList.remove("focused");
});

// Modal open: focus first control, restore later
let prev;
function openModal(modal) {
  prev = document.activeElement;
  modal.showModal?.() ?? modal.removeAttribute("hidden");
  modal.querySelector("button, [href], input")?.focus();
}
function closeModal(modal) {
  modal.close?.() ?? modal.setAttribute("hidden", "");
  prev?.focus();
}

// Programmatic-only focus target
const panel = document.querySelector("#panel");
panel.tabIndex = -1;
panel.focus({ preventScroll: true });

// Detect focus leaving container
container.addEventListener("focusout", (e) => {
  if (!container.contains(e.relatedTarget)) {
    // focus left container
  }
});

// Roving tabindex pattern (toolbar)
function setActive(items, active) {
  items.forEach((el) => (el.tabIndex = el === active ? 0 : -1));
  active.focus();
}
```

```js
// Don’t steal focus on every render
if (document.activeElement !== input) input.focus();
```

## ⚠️ Pitfalls [#️-pitfalls]

* `focus`/`blur` don’t bubble — use `focusin`/`focusout` for delegation.
* Positive `tabindex` creates maintenance nightmares — prefer DOM order + `0`/`-1`.
* Focusing hidden elements fails or confuses AT — show first, then focus.
* `preventScroll` support matters for sticky headers.
* Removing a focused node moves focus to `<body>` — restore deliberately.

## 🔗 Related [#-related]

* [events.md](/docs/javascript/dom/events) — focus events
* [forms\_validation.md](/docs/javascript/dom/forms-validation) — form UX
* [../Html/dialog.md](/docs/javascript/../html/dialog) — modal focus
* [../Html/accessibility.md](/docs/javascript/../html/accessibility) — a11y
* [../Html/aria.md](/docs/javascript/../html/aria) — aria-activedescendant


---

# Forms (/docs/javascript/dom/form)



# Forms [#forms]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

HTML forms expose controls, validation, and submission APIs. Use `FormData`, constraint validation, and `submit` / `input` / `change` events. Prefer progressive enhancement over hijacking every submit blindly.

## 🔧 Core concepts [#-core-concepts]

* **Elements**: `form.elements`, named access `form.email`, `HTMLFormControlsCollection`.
* **Events**: `submit`, `input`, `change`, `invalid`, `reset`.
* **Validation**: `checkValidity`, `reportValidity`, `setCustomValidity`, `:valid`/`:invalid`.
* **`FormData`**: `new FormData(form)` — key/value including files.
* **Submit**: `requestSubmit()` runs validation; `form.submit()` does not.

```js
form.addEventListener("submit", async (e) => {
  e.preventDefault();
  const data = new FormData(form);
  await fetch(form.action, { method: form.method, body: data });
});
```

## 💡 Examples [#-examples]

```js
const form = document.querySelector("#signup");
const email = form.elements.namedItem("email");

form.addEventListener("submit", (e) => {
  if (!form.checkValidity()) {
    e.preventDefault();
    form.reportValidity();
    return;
  }
  // native submit continues if not prevented
});

email.addEventListener("input", () => {
  if (email.validity.typeMismatch) {
    email.setCustomValidity("Enter a valid email");
  } else {
    email.setCustomValidity("");
  }
});

// FormData inspection
const fd = new FormData(form);
for (const [k, v] of fd) console.log(k, v);
fd.append("source", "web");

// JSON instead of multipart
async function submitJson(form) {
  const data = Object.fromEntries(new FormData(form).entries());
  await fetch("/api", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
  });
}

// Programmatic submit with validation
form.requestSubmit();
```

```js
// File input
const file = form.elements.file.files?.[0];
if (file) console.log(file.name, file.size);
```

## ⚠️ Pitfalls [#️-pitfalls]

* `form.submit()` skips submit event and constraint validation — use `requestSubmit()`.
* Unnamed controls are omitted from `FormData`.
* Disabled fields are excluded from submission.
* Multiple controls with the same name need `getAll`.
* Don’t forget `enctype` for files (`multipart/form-data` is automatic with `FormData` + fetch).

## 🔗 Related [#-related]

* [events.md](/docs/javascript/dom/events) — submit/input
* [attributes.md](/docs/javascript/dom/attributes) — required / name
* [selectors.md](/docs/javascript/dom/selectors) — finding controls
* [../fetch.md](/docs/javascript/fetch) — posting FormData
* [../json.md](/docs/javascript/json) — JSON bodies
* [../encode.md](/docs/javascript/encode) — URLSearchParams
* [datatransfer.md](/docs/javascript/dom/datatransfer) — file drops


---

# Forms Validation (/docs/javascript/dom/forms-validation)



# Forms Validation [#forms-validation]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Constraint Validation API gives native form checks: `required`, `type`, `pattern`, `min`/`max`, `minlength`/`maxlength`, and custom validity. Prefer native UI + progressive enhancement; use `setCustomValidity` for app-specific rules and `checkValidity` / `reportValidity` to trigger them.

## 🔧 Core concepts [#-core-concepts]

* **Element APIs**: `checkValidity()`, `reportValidity()`, `setCustomValidity(msg)`, `validity`, `validationMessage`, `willValidate`.
* **Form**: `form.checkValidity()`, `form.reportValidity()`, `novalidate` attribute.
* **Events**: `invalid` (cancelable per control), `input`/`change` to clear custom errors.
* **`validity` flags**: `valueMissing`, `typeMismatch`, `patternMismatch`, `tooLong`, `tooShort`, `rangeUnderflow`, `rangeOverflow`, `stepMismatch`, `customError`, `valid`.
* **CSS**: `:valid`, `:invalid`, `:user-valid`, `:user-invalid`.

```js
email.setCustomValidity(
  email.validity.typeMismatch ? "Enter a valid email" : "",
);
form.reportValidity();
```

## 💡 Examples [#-examples]

```js
const form = document.querySelector("form");
const password = form.elements.password;
const confirm = form.elements.confirm;

function syncPasswords() {
  confirm.setCustomValidity(
    confirm.value !== password.value ? "Passwords must match" : "",
  );
}
password.addEventListener("input", syncPasswords);
confirm.addEventListener("input", syncPasswords);

form.addEventListener("submit", (e) => {
  syncPasswords();
  if (!form.checkValidity()) {
    e.preventDefault();
    form.reportValidity();
    return;
  }
  e.preventDefault();
  submitData(new FormData(form));
});

// Live field message
input.addEventListener("invalid", (e) => {
  e.preventDefault(); // block browser bubble if custom UI
  showError(input, input.validationMessage);
});
input.addEventListener("input", () => {
  input.setCustomValidity("");
  clearError(input);
});

// Programmatic check without UI
if (username.validity.tooShort) {
  /* ... */
}
```

```html
<input
  name="username"
  required
  minlength="3"
  pattern="[a-z0-9_]+"
  title="Letters, numbers, underscore"
/>
```

## ⚠️ Pitfalls [#️-pitfalls]

* `setCustomValidity("msg")` makes the field invalid until cleared with `""`.
* `novalidate` on form skips native checks — you must validate yourself.
* Don’t rely only on client validation — always validate on the server.
* `:invalid` styles can show too early — prefer `:user-invalid` where supported.
* Disabled fields are barred from validation / submission.

## 🔗 Related [#-related]

* [form.md](/docs/javascript/dom/form) — form controls
* [../Html/form.md](/docs/javascript/../html/form) — form HTML
* [../Html/input.md](/docs/javascript/../html/input) — input types
* [focus\_blur.md](/docs/javascript/dom/focus-blur) — focusing first error
* [events.md](/docs/javascript/dom/events) — submit/invalid


---

# Geolocation (/docs/javascript/dom/geolocation)



# Geolocation [#geolocation]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`navigator.geolocation` provides the device’s geographic position (GPS/Wi‑Fi/IP heuristics) after user permission. Use for maps, check-ins, and local results. Always handle denial, timeouts, and inaccurate coords; prefer watch only while needed.

## 🔧 Core concepts [#-core-concepts]

* **One-shot**: `getCurrentPosition(success, error?, options?)`.
* **Watch**: `watchPosition(...)` → watchId; clear with `clearWatch(id)`.
* **Position**: `coords.latitude`, `longitude`, `accuracy`, `altitude`, `heading`, `speed`, `timestamp`.
* **Options**: `enableHighAccuracy`, `timeout`, `maximumAge`.
* **Errors**: `PERMISSION_DENIED`, `POSITION_UNAVAILABLE`, `TIMEOUT`.
* **Secure context** required in modern browsers.

```js
navigator.geolocation.getCurrentPosition(
  (pos) => console.log(pos.coords.latitude, pos.coords.longitude),
  (err) => console.error(err.code, err.message),
  { enableHighAccuracy: true, timeout: 10_000, maximumAge: 60_000 },
);
```

## 💡 Examples [#-examples]

```js
function getPosition(options) {
  return new Promise((resolve, reject) => {
    if (!navigator.geolocation) {
      reject(new Error("unsupported"));
      return;
    }
    navigator.geolocation.getCurrentPosition(resolve, reject, options);
  });
}

const pos = await getPosition({
  enableHighAccuracy: false,
  timeout: 8000,
  maximumAge: 300_000,
});
const { latitude: lat, longitude: lng, accuracy } = pos.coords;

// Watch while map is open
const id = navigator.geolocation.watchPosition(
  (p) => map.setCenter(p.coords),
  (e) => console.warn(e),
  { enableHighAccuracy: true },
);
// later
navigator.geolocation.clearWatch(id);

// Permissions API (where supported)
const status = await navigator.permissions.query({ name: "geolocation" });
status.onchange = () => console.log(status.state);
```

```js
// Distance helper (Haversine km)
function km(a, b) {
  const R = 6371;
  const dLat = ((b.lat - a.lat) * Math.PI) / 180;
  const dLon = ((b.lng - a.lng) * Math.PI) / 180;
  const s =
    Math.sin(dLat / 2) ** 2 +
    Math.cos((a.lat * Math.PI) / 180) *
      Math.cos((b.lat * Math.PI) / 180) *
      Math.sin(dLon / 2) ** 2;
  return 2 * R * Math.asin(Math.sqrt(s));
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Permission prompts need a user gesture in many browsers — don’t call on page load without context.
* `accuracy` can be hundreds of meters indoors — show uncertainty to users.
* High accuracy drains battery — clear watches promptly.
* Spoofing / VPNs possible — never treat as strong auth.
* Desktop may use IP geolocation — expect coarse results.

## 🔗 Related [#-related]

* [../abort\_controller.md](/docs/javascript/abort-controller) — timeouts pattern
* [../promise.md](/docs/javascript/promise) — promisify callbacks
* [events.md](/docs/javascript/dom/events) — user activation
* [../intl.md](/docs/javascript/intl) — formatting coords for display
* [window.md](/docs/javascript/dom/window) — navigator


---

# Intersection Observer (/docs/javascript/dom/intersection-observer)



# Intersection Observer [#intersection-observer]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`IntersectionObserver` asynchronously reports when a target element’s visibility crosses thresholds relative to a root (viewport or element). Use it for lazy-loading, infinite scroll, ad viewability, and scroll-driven UI — without scroll event spam.

## 🔧 Core concepts [#-core-concepts]

* **Create**: `new IntersectionObserver(callback, options)`.
* **Options**: `root`, `rootMargin`, `threshold` (0–1 or array).
* **Callback**: receives `entries` and the observer; runs off the main scroll path.
* **Entry**: `isIntersecting`, `intersectionRatio`, `boundingClientRect`, `rootBounds`, `target`, `time`.
* **Control**: `observe`, `unobserve`, `disconnect`, `takeRecords`.

```js
const io = new IntersectionObserver((entries) => {
  for (const e of entries) {
    if (e.isIntersecting) load(e.target);
  }
});
io.observe(document.querySelector("img[data-src]"));
```

## 💡 Examples [#-examples]

```js
// Lazy images
const io = new IntersectionObserver(
  (entries, obs) => {
    for (const e of entries) {
      if (!e.isIntersecting) continue;
      const img = e.target;
      img.src = img.dataset.src;
      obs.unobserve(img);
    }
  },
  { rootMargin: "200px 0px", threshold: 0.01 },
);
document.querySelectorAll("img[data-src]").forEach((img) => io.observe(img));

// Infinite scroll sentinel
const sentinel = document.querySelector("#sent");
new IntersectionObserver(async ([e]) => {
  if (e.isIntersecting) await loadMore();
}).observe(sentinel);

// Multiple thresholds for progress
new IntersectionObserver(
  ([e]) => {
    bar.style.width = `${e.intersectionRatio * 100}%`;
  },
  { threshold: Array.from({ length: 21 }, (_, i) => i / 20) },
).observe(article);

// Section spy / active nav
const sections = document.querySelectorAll("section[id]");
const navIo = new IntersectionObserver(
  (entries) => {
    entries.forEach((e) => {
      const link = document.querySelector(`a[href="#${e.target.id}"]`);
      link?.classList.toggle("active", e.isIntersecting);
    });
  },
  { rootMargin: "-40% 0px -40% 0px", threshold: 0 },
);
sections.forEach((s) => navIo.observe(s));
```

## ⚠️ Pitfalls [#️-pitfalls]

* `root` must be an ancestor of the target (or `null` for viewport).
* Zero-size targets may never intersect — ensure measurable box.
* Callbacks are batched and async — not frame-perfect with scroll position.
* Always `unobserve`/`disconnect` when done to avoid leaks.
* `rootMargin` uses CSS margin syntax — percentages resolve against root size.

## 🔗 Related [#-related]

* [mutation\_observer.md](/docs/javascript/dom/mutation-observer) — DOM change watching
* [resize\_observer.md](/docs/javascript/dom/resize-observer) — size changes
* [events.md](/docs/javascript/dom/events) — scroll events alternative
* [position.md](/docs/javascript/dom/position) — geometry
* [../timers.md](/docs/javascript/timers) — rAF pairing


---

# MediaQueryList (/docs/javascript/dom/media-query-list)



# MediaQueryList [#mediaquerylist]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`window.matchMedia(query)` returns a `MediaQueryList` for CSS media queries in JS — responsive behavior, dark mode detection, and reduced-motion preferences. Listen with `addEventListener("change", ...)` (not deprecated `addListener` in new code).

## 🔧 Core concepts [#-core-concepts]

* **Create**: `const mql = matchMedia("(min-width: 768px)")`.
* **`mql.matches`**: boolean current state.
* **`mql.media`**: serialized query string.
* **Events**: `change` when match flips.
* **Common queries**: width, `prefers-color-scheme`, `prefers-reduced-motion`, `hover`, `pointer`, `display-mode`.
* **CSS sync**: same syntax as `@media`.

```js
const wide = matchMedia("(min-width: 900px)");
if (wide.matches) enableGrid();
wide.addEventListener("change", (e) => {
  e.matches ? enableGrid() : enableStack();
});
```

## 💡 Examples [#-examples]

```js
// Dark mode preference
const dark = matchMedia("(prefers-color-scheme: dark)");
function applyTheme() {
  document.documentElement.dataset.theme = dark.matches ? "dark" : "light";
}
applyTheme();
dark.addEventListener("change", applyTheme);

// Reduced motion
const motion = matchMedia("(prefers-reduced-motion: reduce)");
if (!motion.matches) startAnimation();

// Hover-capable devices
const canHover = matchMedia("(hover: hover) and (pointer: fine)").matches;

// PWA display mode
matchMedia("(display-mode: standalone)").matches;

// Helper
function onMedia(query, cb) {
  const mql = matchMedia(query);
  cb(mql.matches);
  const handler = (e) => cb(e.matches);
  mql.addEventListener("change", handler);
  return () => mql.removeEventListener("change", handler);
}

const stop = onMedia("(max-width: 600px)", (isMobile) => {
  nav.dataset.mode = isMobile ? "drawer" : "bar";
});
```

```js
// Older Safari used addListener/removeListener
// mql.addListener(fn); // legacy
```

## ⚠️ Pitfalls [#️-pitfalls]

* Don’t parse `window.innerWidth` for breakpoints you already express in CSS — prefer `matchMedia` for parity.
* Evaluate once at load isn’t enough for rotatable devices — listen for `change`.
* Unit differences (`em` vs `px`) follow CSS rules relative to initial viewport / font.
* `matchMedia` is sync and cheap — still avoid creating thousands of listeners.
* JS theme overrides should respect user preference unless explicitly overridden.

## 🔗 Related [#-related]

* [../CSS/media\_queries.md](/docs/javascript/../css/media-queries) — CSS `@media`
* [../CSS/dark\_mode.md](/docs/javascript/../css/dark-mode) — color schemes
* [events.md](/docs/javascript/dom/events) — change events
* [screen.md](/docs/javascript/dom/screen) — screen metrics
* [window.md](/docs/javascript/dom/window) — viewport


---

# Mutation Methods & Observers (/docs/javascript/dom/mutation-methods)



# Mutation Methods & Observers [#mutation-methods--observers]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

Mutate the tree with node methods (`append`, `remove`, `replaceChildren`, …) and observe changes with `MutationObserver`. Use observers for integrations and accessibility hooks — not as a substitute for app state.

## 🔧 Core concepts [#-core-concepts]

* **Child mutation**: `append`, `prepend`, `replaceChildren`, `replaceWith`, `remove`.
* **Legacy**: `appendChild`, `insertBefore`, `removeChild`, `replaceChild`.
* **`MutationObserver`**: callback with `MutationRecord[]`.
* **Observe options**: `childList`, `subtree`, `attributes`, `attributeFilter`, `characterData`.
* **Records**: `type`, `target`, `addedNodes`, `removedNodes`, `attributeName`, `oldValue`.

```js
parent.replaceChildren(...newItems);
```

## 💡 Examples [#-examples]

```js
const list = document.querySelector("#list");
list.append(li1, li2);
list.prepend(header);
old.replaceWith(fresh);
empty.remove();
list.replaceChildren(); // clear

// Observer
const obs = new MutationObserver((records) => {
  for (const r of records) {
    if (r.type === "childList") {
      r.addedNodes.forEach((n) => {
        if (n.nodeType === Node.ELEMENT_NODE) enhance(n);
      });
    }
    if (r.type === "attributes" && r.attributeName === "class") {
      syncClass(r.target);
    }
  }
});

obs.observe(list, {
  childList: true,
  subtree: true,
  attributes: true,
  attributeFilter: ["class", "aria-expanded"],
  attributeOldValue: true,
});

// Later
obs.disconnect();
```

```js
// Batch read after mutations
requestAnimationFrame(() => {
  const h = list.getBoundingClientRect().height;
});

// takeRecords drains the queue synchronously
const pending = obs.takeRecords();
for (const r of pending) handle(r);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Observers are async (microtask) — don’t expect sync delivery mid-script.
* Observing `attributes: true` without `attributeFilter` is noisy.
* Mutating the DOM inside the callback can recurse — guard or disconnect temporarily.
* Live `NodeList` from `childNodes` changes as you mutate — copy first if needed.
* Prefer explicit app updates over observing your own renders.

## 🔗 Related [#-related]

* [create\_add\_remove.md](/docs/javascript/dom/create-add-remove) — creating nodes
* [content\_methods.md](/docs/javascript/dom/content-methods) — content updates
* [events.md](/docs/javascript/dom/events) — user-driven changes
* [attributes.md](/docs/javascript/dom/attributes) — attribute mutations
* [selectors.md](/docs/javascript/dom/selectors) — finding roots
* [../async.md](/docs/javascript/async) — microtask timing


---

# Mutation Observer (/docs/javascript/dom/mutation-observer)



# Mutation Observer [#mutation-observer]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`MutationObserver` notifies you of DOM tree changes: child lists, attributes, and character data. Prefer it over deprecated mutation events. Ideal for integrating with third-party widgets, reacting to SPA renders, and building developer tools — use sparingly in hot paths.

## 🔧 Core concepts [#-core-concepts]

* **Create**: `new MutationObserver(callback)`.
* **`observe(target, options)`**: start watching.
* **Options**: `childList`, `attributes`, `characterData`, `subtree`, `attributeFilter`, `attributeOldValue`, `characterDataOldValue`.
* **Records**: `type`, `target`, `addedNodes`, `removedNodes`, `attributeName`, `oldValue`, etc.
* **`disconnect()`*&#x2A; / &#x2A;*`takeRecords()`**: stop or flush queue.
* Delivered as microtasks after mutations settle.

```js
const mo = new MutationObserver((records) => {
  for (const r of records) console.log(r.type, r.target);
});
mo.observe(document.body, { childList: true, subtree: true });
```

## 💡 Examples [#-examples]

```js
// Watch attribute changes on one element
mo.observe(el, {
  attributes: true,
  attributeFilter: ["class", "aria-expanded"],
  attributeOldValue: true,
});

// React when a node appears
function whenAdded(selector, root = document.body) {
  return new Promise((resolve) => {
    const found = root.querySelector(selector);
    if (found) return resolve(found);
    const obs = new MutationObserver(() => {
      const el = root.querySelector(selector);
      if (el) {
        obs.disconnect();
        resolve(el);
      }
    });
    obs.observe(root, { childList: true, subtree: true });
  });
}

// Sanitize added nodes
const sanitizer = new MutationObserver((records) => {
  for (const r of records) {
    r.addedNodes.forEach((node) => {
      if (node.nodeType === 1) scrub(node);
    });
  }
});
sanitizer.observe(container, { childList: true, subtree: true });

// Character data
mo.observe(textNode, { characterData: true, characterDataOldValue: true });
```

```js
// Avoid feedback loops
let applying = false;
const obs = new MutationObserver(() => {
  if (applying) return;
  applying = true;
  sync();
  applying = false;
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Observing `document` with `subtree: true` can flood callbacks — narrow the root/filter.
* Mutations you make inside the callback can re-trigger — guard with flags or disconnect temporarily.
* Does not observe computed style / resize — use ResizeObserver / IntersectionObserver.
* `attributeFilter` is ignored unless `attributes: true`.
* Memory: disconnect when components unmount.

## 🔗 Related [#-related]

* [intersection\_observer.md](/docs/javascript/dom/intersection-observer) — visibility
* [resize\_observer.md](/docs/javascript/dom/resize-observer) — size
* [mutation\_methods.md](/docs/javascript/dom/mutation-methods) — DOM mutations
* [create\_add\_remove.md](/docs/javascript/dom/create-add-remove) — creating nodes
* [../event\_loop.md](/docs/javascript/event-loop) — microtask delivery


---

# Navigation (Location & History) (/docs/javascript/dom/navigation)



# Navigation (Location & History) [#navigation-location--history]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

`location` describes the current URL; `history` manages the session history stack. For SPAs, combine `pushState` / `replaceState` with `popstate` and the Navigation API where available.

## 🔧 Core concepts [#-core-concepts]

* **`location`**: `href`, `origin`, `pathname`, `search`, `hash`, `assign`, `replace`, `reload`.
* **`history`**: `length`, `state`, `pushState`, `replaceState`, `back`, `forward`, `go`.
* **Events**: `popstate`, `hashchange`.
* **Navigation API** (modern): `navigation.navigate()`, `navigate` event (progressive enhancement).
* **URL API**: parse `location.href` with `new URL(...)`.

```js
history.pushState({ page: 2 }, "", "/page/2");
```

## 💡 Examples [#-examples]

```js
// Read
const url = new URL(location.href);
const page = url.searchParams.get("page");

// Navigate
location.assign("/home"); // pushes history
location.replace("/login"); // no extra history entry
location.reload();

// SPA route change
function navigate(path, state = {}) {
  history.pushState(state, "", path);
  render(path, state);
}

window.addEventListener("popstate", (e) => {
  render(location.pathname, e.state);
});

// Hash routing
window.addEventListener("hashchange", () => {
  renderHash(location.hash.slice(1));
});

// Query update without full reload
function setQuery(key, value) {
  const u = new URL(location.href);
  u.searchParams.set(key, value);
  history.replaceState(history.state, "", u);
}
```

```js
// Guard unload
window.addEventListener("beforeunload", (e) => {
  if (isDirty) {
    e.preventDefault();
    e.returnValue = "";
  }
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* `pushState` does not trigger `popstate` — you must render yourself.
* Cross-origin `location` access throws — only same-origin details are readable.
* Large `history.state` objects are cloned — keep them small/serializable.
* `location.search` includes `?`; prefer `URLSearchParams`.
* `beforeunload` prompts are restricted/browser-dependent.

## 🔗 Related [#-related]

* [window.md](/docs/javascript/dom/window) — window object
* [../url.md](/docs/javascript/url) — URL / search params
* [../encode.md](/docs/javascript/encode) — encoding paths
* [events.md](/docs/javascript/dom/events) — popstate / hashchange
* [document\_methods.md](/docs/javascript/dom/document-methods) — document.URL
* [storage.md](/docs/javascript/dom/storage) — persisting UI state


---

# Position & Geometry (/docs/javascript/dom/position)



# Position & Geometry [#position--geometry]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

Measure layout with `getBoundingClientRect`, offset/scroll properties, and `IntersectionObserver` / `ResizeObserver`. Batch reads and writes to avoid layout thrashing.

## 🔧 Core concepts [#-core-concepts]

* **Viewport box**: `getBoundingClientRect()` → `x`, `y`, `width`, `height`, `top`, `right`, `bottom`, `left` (CSS pixels, viewport-relative).
* **Offset**: `offsetTop`, `offsetLeft`, `offsetWidth`, `offsetHeight`, `offsetParent`.
* **Client**: `clientWidth` / `clientHeight` (padding box, no scrollbar).
* **Scroll**: `scrollTop`, `scrollLeft`, `scrollWidth`, `scrollHeight`, `scrollTo`.
* **Observers**: `ResizeObserver`, `IntersectionObserver`.
* **Visual viewport**: `window.visualViewport` (mobile chrome).

```js
const r = el.getBoundingClientRect();
const visible = r.top < innerHeight && r.bottom > 0;
```

## 💡 Examples [#-examples]

```js
// Center in viewport?
function isInViewport(el) {
  const r = el.getBoundingClientRect();
  return r.top >= 0 && r.bottom <= window.innerHeight;
}

// Scroll into view
el.scrollIntoView({ behavior: "smooth", block: "nearest" });

// Document position
function pageOffset(el) {
  const r = el.getBoundingClientRect();
  return {
    top: r.top + window.scrollY,
    left: r.left + window.scrollX,
  };
}

// ResizeObserver
const ro = new ResizeObserver((entries) => {
  for (const entry of entries) {
    const { width, height } = entry.contentRect;
    chart.resize(width, height);
  }
});
ro.observe(container);

// IntersectionObserver lazy-load
const io = new IntersectionObserver(
  (entries, obs) => {
    for (const e of entries) {
      if (!e.isIntersecting) continue;
      e.target.src = e.target.dataset.src;
      obs.unobserve(e.target);
    }
  },
  { rootMargin: "100px" },
);
document.querySelectorAll("img[data-src]").forEach((img) => io.observe(img));
```

```js
// Avoid thrashing: read all, then write
const heights = items.map((el) => el.getBoundingClientRect().height);
items.forEach((el, i) => {
  el.style.minHeight = `${Math.max(...heights)}px`;
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Interleaving measure and mutate causes forced synchronous layout.
* `getBoundingClientRect` is viewport-relative — add `scrollX/Y` for document coords.
* Transforms affect bounding rects; offset props may differ.
* `offsetParent` can be `null` for fixed/hidden elements.
* Subpixel floats — round when comparing to integers.

## 🔗 Related [#-related]

* [window.md](/docs/javascript/dom/window) — scrollX / innerHeight
* [screen.md](/docs/javascript/dom/screen) — screen metrics
* [class.md](/docs/javascript/dom/class) — class-driven layout
* [events.md](/docs/javascript/dom/events) — scroll / resize
* [selectors.md](/docs/javascript/dom/selectors) — targeting elements
* [../math.md](/docs/javascript/math) — clamping / rounding


---

# Range & Selection (/docs/javascript/dom/range)



# Range & Selection [#range--selection]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

A `Range` represents a fragment of the document between two boundary points. `Selection` (from `window.getSelection()`) is the user highlight, often backed by one or more ranges. Used for editing, measuring text, and inserting at the caret.

## 🔧 Core concepts [#-core-concepts]

* **Create**: `document.createRange()`, `Range` methods on selection.
* **Boundaries**: `setStart`, `setEnd`, `selectNode`, `selectNodeContents`, `collapse`.
* **Content**: `cloneContents`, `extractContents`, `deleteContents`, `insertNode`, `surroundContents`.
* **Geometry**: `getBoundingClientRect`, `getClientRects`.
* **Selection**: `getSelection()`, `addRange`, `removeAllRanges`, `collapse`, `toString()`.

```js
const range = document.createRange();
range.selectNodeContents(el);
```

## 💡 Examples [#-examples]

```js
// Select all text in an element
const sel = window.getSelection();
const range = document.createRange();
range.selectNodeContents(el);
sel.removeAllRanges();
sel.addRange(range);

// Insert at caret
function insertAtCaret(node) {
  const sel = window.getSelection();
  if (!sel.rangeCount) return;
  const range = sel.getRangeAt(0);
  range.deleteContents();
  range.insertNode(node);
  range.setStartAfter(node);
  range.collapse(true);
  sel.removeAllRanges();
  sel.addRange(range);
}

// Extract HTML fragment
const r = document.createRange();
r.setStart(startNode, startOffset);
r.setEnd(endNode, endOffset);
const frag = r.cloneContents();

// Caret coordinates (approx)
function caretRect() {
  const sel = getSelection();
  if (!sel.rangeCount) return null;
  const r = sel.getRangeAt(0).cloneRange();
  r.collapse(true);
  return r.getBoundingClientRect();
}

// Wrap selection
function boldSelection() {
  const sel = getSelection();
  if (!sel.rangeCount || sel.isCollapsed) return;
  const strong = document.createElement("strong");
  sel.getRangeAt(0).surroundContents(strong);
}
```

```js
// createContextualFragment
const html = document.createRange().createContextualFragment("<em>x</em>");
```

## ⚠️ Pitfalls [#️-pitfalls]

* `surroundContents` throws if the range partially selects non-text nodes — split carefully.
* Selection APIs differ in iframes — use the iframe’s `window.getSelection()`.
* Mutating DOM often invalidates live ranges — clone or re-create.
* Multi-range selections exist in some browsers (Firefox) — don’t assume one range.
* Measuring collapsed ranges can yield zero-size rects — insert a temporary marker if needed.

## 🔗 Related [#-related]

* [content\_methods.md](/docs/javascript/dom/content-methods) — text editing
* [create\_add\_remove.md](/docs/javascript/dom/create-add-remove) — insertNode
* [events.md](/docs/javascript/dom/events) — selectionchange
* [document\_methods.md](/docs/javascript/dom/document-methods) — createRange
* [position.md](/docs/javascript/dom/position) — rects
* [window.md](/docs/javascript/dom/window) — getSelection


---

# Resize Observer (/docs/javascript/dom/resize-observer)



# Resize Observer [#resize-observer]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`ResizeObserver` fires when an Element’s size changes — more precise than `window.resize` for component-level layouts, container queries polyfills, and chart reflows. Observe content box, border box, or device-pixel content box.

## 🔧 Core concepts [#-core-concepts]

* **Create**: `new ResizeObserver(callback)`.
* **`observe(el, \{ box \})`**: `content-box` (default), `border-box`, `device-pixel-content-box`.
* **Entry**: `contentRect`, `borderBoxSize`, `contentBoxSize`, `devicePixelContentBoxSize`, `target`.
* **`unobserve` / `disconnect`**: cleanup.
* Fired before paint after layout; avoid layout loops.

```js
const ro = new ResizeObserver((entries) => {
  for (const e of entries) {
    const { width, height } = e.contentRect;
    chart.resize(width, height);
  }
});
ro.observe(container);
```

## 💡 Examples [#-examples]

```js
// Prefer box sizes arrays (newer)
new ResizeObserver((entries) => {
  const e = entries[0];
  const [size] = e.contentBoxSize;
  const w = size.inlineSize;
  const h = size.blockSize;
  render(w, h);
}).observe(el, { box: "content-box" });

// Border box for total footprint
ro.observe(el, { box: "border-box" });

// Responsive component without window listener
function mount(el) {
  const ro = new ResizeObserver(([e]) => {
    el.dataset.wide = String(e.contentRect.width > 600);
  });
  ro.observe(el);
  return () => ro.disconnect();
}

// Canvas backing store
const canvas = document.querySelector("canvas");
new ResizeObserver(() => {
  const dpr = devicePixelRatio;
  const { width, height } = canvas.getBoundingClientRect();
  canvas.width = Math.round(width * dpr);
  canvas.height = Math.round(height * dpr);
  draw();
}).observe(canvas);
```

```js
// Guard infinite resize loops
let frame;
const ro = new ResizeObserver(() => {
  cancelAnimationFrame(frame);
  frame = requestAnimationFrame(update);
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Changing size inside the callback can cause observation loops — batch via rAF and check thresholds.
* `contentRect` is legacy-ish; prefer `contentBoxSize` / `borderBoxSize` (arrays for fragmented boxes).
* SVG / table quirks exist — verify in target browsers.
* Not a substitute for CSS container queries when pure CSS suffices.
* Disconnect on teardown.

## 🔗 Related [#-related]

* [intersection\_observer.md](/docs/javascript/dom/intersection-observer) — visibility
* [mutation\_observer.md](/docs/javascript/dom/mutation-observer) — DOM changes
* [position.md](/docs/javascript/dom/position) — measurements
* [../timers.md](/docs/javascript/timers) — rAF
* [cssom.md](/docs/javascript/dom/cssom) — computed sizes


---

# Screen (/docs/javascript/dom/screen)



# Screen [#screen]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

`window.screen` exposes information about the output display: pixel dimensions, color depth, and orientation. Pair with `window` viewport metrics and media queries for responsive behavior — screen size ≠ layout viewport.

## 🔧 Core concepts [#-core-concepts]

* **Size**: `screen.width`, `screen.height` (full screen).
* **Available**: `screen.availWidth`, `screen.availHeight` (minus OS chrome).
* **Color**: `colorDepth`, `pixelDepth`.
* **Orientation**: `screen.orientation.type`, `angle`, `lock()` / `unlock()` (secure contexts / UX rules).
* **Multi-screen** (experimental): `window.getScreenDetails()` where permitted.
* **Device pixels**: `window.devicePixelRatio`.

```js
console.log(screen.width, screen.height, devicePixelRatio);
```

## 💡 Examples [#-examples]

```js
// Basic readout
const info = {
  screen: `${screen.width}×${screen.height}`,
  avail: `${screen.availWidth}×${screen.availHeight}`,
  dpr: devicePixelRatio,
  orientation: screen.orientation?.type,
};

// Orientation change
screen.orientation?.addEventListener("change", () => {
  console.log(screen.orientation.type, screen.orientation.angle);
});

// Prefer CSS / matchMedia for layout
const mq = matchMedia("(orientation: portrait)");
mq.addEventListener("change", (e) => {
  document.body.classList.toggle("portrait", e.matches);
});

// Lock landscape (may require fullscreen + gesture)
async function lockLandscape() {
  try {
    await document.documentElement.requestFullscreen();
    await screen.orientation.lock("landscape");
  } catch (err) {
    console.warn("orientation lock failed", err);
  }
}

// Canvas backing store
canvas.width = Math.floor(cssWidth * devicePixelRatio);
canvas.height = Math.floor(cssHeight * devicePixelRatio);
ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);
```

```js
// Don’t use screen.width for responsive layout — use viewport
const layoutWidth = document.documentElement.clientWidth;
```

## ⚠️ Pitfalls [#️-pitfalls]

* `screen.width` is not the browser viewport — use `innerWidth` / `clientWidth` for layout.
* Orientation lock is heavily gated and often fails outside fullscreen/PWA.
* Extended screen APIs need permission and are not universal.
* Browser zoom affects CSS pixels vs device pixels — test with DPR ≠ 1.
* Values can change when moving windows across monitors.

## 🔗 Related [#-related]

* [window.md](/docs/javascript/dom/window) — viewport metrics
* [position.md](/docs/javascript/dom/position) — element geometry
* [events.md](/docs/javascript/dom/events) — resize / orientation
* [navigation.md](/docs/javascript/dom/navigation) — fullscreen flows
* [../math.md](/docs/javascript/math) — rounding DPR sizes
* [../api.md](/docs/javascript/api) — media / display APIs


---

# Selectors (/docs/javascript/dom/selectors)



# Selectors [#selectors]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

Find nodes with CSS selectors via `querySelector` / `querySelectorAll`, or with id/class/tag helpers. Use `matches` and `closest` for event delegation. Escape dynamic values with `CSS.escape`.

## 🔧 Core concepts [#-core-concepts]

* **Single**: `parent.querySelector(sel)` → first match or `null`.
* **All**: `querySelectorAll` → static `NodeList`.
* **Id**: `getElementById` (document only) — fastest for ids.
* **Live collections**: `getElementsByClassName`, `getElementsByTagName`, `getElementsByName`.
* **Test**: `el.matches(sel)`, `el.closest(sel)`.
* **Scope**: query relative to any `Element` / `Document` / `DocumentFragment`.

```js
const item = document.querySelector(".list > li.active");
const items = document.querySelectorAll("[data-id]");
```

## 💡 Examples [#-examples]

```js
const root = document.querySelector("#app");
const btn = root.querySelector("button[type='submit']");
const rows = root.querySelectorAll("tbody tr");

// Convert to array
const arr = [...rows];

// Delegation helpers
list.addEventListener("click", (e) => {
  const row = e.target.closest("tr[data-id]");
  if (!row || !list.contains(row)) return;
  if (e.target.matches("button.delete")) {
    row.remove();
  }
});

// Dynamic id/class
const id = "section.1";
document.querySelector(`#${CSS.escape(id)}`);

// Attribute selectors
document.querySelectorAll('input[name="tags"]:checked');
document.querySelectorAll("a[href^='https://']");

// :scope in modern engines
root.querySelectorAll(":scope > .child");
```

```js
// Prefer getElementById for plain ids
document.getElementById("app");

// Live vs static
const live = document.getElementsByClassName("item");
const staticList = document.querySelectorAll(".item");
const extra = document.createElement("div");
extra.className = "item";
document.body.append(extra);
console.log(live.length, staticList.length); // live grew; static did not
```

## ⚠️ Pitfalls [#️-pitfalls]

* Invalid selectors throw `DOMException` — escape user input.
* `querySelectorAll` is a snapshot; live HTMLCollections update as the DOM changes.
* `closest` goes upward including itself — check `matches` when you need only ancestors.
* Descendant queries from a detached tree only search that subtree.
* Over-specific selectors are brittle — prefer stable `data-*` hooks.

## 🔗 Related [#-related]

* [document\_methods.md](/docs/javascript/dom/document-methods) — document queries
* [events.md](/docs/javascript/dom/events) — delegation
* [attributes.md](/docs/javascript/dom/attributes) — data attributes
* [class.md](/docs/javascript/dom/class) — class tokens
* [create\_add\_remove.md](/docs/javascript/dom/create-add-remove) — building trees
* [../strings.md](/docs/javascript/strings) — building selector strings


---

# Shadow DOM (/docs/javascript/dom/shadow-dom)



# Shadow DOM [#shadow-dom]

*JavaScript DOM · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Shadow DOM attaches an encapsulated DOM tree to an element. Styles and nodes inside the shadow root stay mostly isolated from the page, enabling component CSS without global leaks. Open mode exposes `shadowRoot`; closed hides it.

## 🔧 Core concepts [#-core-concepts]

* **Attach**: `el.attachShadow(\{ mode: "open" | "closed", delegatesFocus?, slotAssignment? \})`.
* **Tree**: `shadowRoot` hosts markup; light DOM children may project via `<slot>`.
* **Style**: shadow styles don’t apply outside (mostly); page styles don’t pierce in (except inheritance of some properties / `::part` / CSS variables).
* **Events**: retargeted so `event.target` appears as the host from outside.
* **Parts**: `part="name"` + `::part(name)` from outside.
* **Slots**: default and named (`<slot name="title">`).

```js
const root = host.attachShadow({ mode: "open" });
root.innerHTML = `
  <style>:host { display: block; }</style>
  <slot></slot>
`;
```

## 💡 Examples [#-examples]

```js
class Card extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: "open" }).innerHTML = `
      <style>
        :host { display: block; border: 1px solid #ccc; }
        ::slotted(h2) { margin: 0; }
        button { color: var(--accent, blue); }
      </style>
      <slot name="title"></slot>
      <div class="body"><slot></slot></div>
      <button part="action">OK</button>
    `;
  }
}
customElements.define("x-card", Card);

// Light DOM usage
// <x-card><h2 slot="title">Hi</h2><p>Body</p></x-card>

// Outside styling via parts
// x-card::part(action) { font-weight: bold; }

// Manual slot assignment (imperative)
const shadow = host.attachShadow({
  mode: "open",
  slotAssignment: "manual",
});
const slot = shadow.querySelector("slot");
slot.assign(nodeA, nodeB);

// Query inside
host.shadowRoot.querySelector("button");
```

```js
// CSS variables pierce shadow
// :root { --accent: tomato; }
```

## ⚠️ Pitfalls [#️-pitfalls]

* Closed mode is not a security boundary — don’t store secrets there.
* `document.querySelector` won’t see shadow internals — pierce with `shadowRoot`.
* Form-associated custom elements need Extra APIs for native form participation.
* Slotted content stays in light DOM — styles with `::slotted` are limited.
* Duplicate `attachShadow` throws — only one shadow root per host.

## 🔗 Related [#-related]

* [custom\_elements.md](/docs/javascript/dom/custom-elements) — defining elements
* [../Html/template\_slot.md](/docs/javascript/../html/template-slot) — slot HTML
* [../Html/web\_components.md](/docs/javascript/../html/web-components) — stack overview
* [selectors.md](/docs/javascript/dom/selectors) — piercing limits
* [events.md](/docs/javascript/dom/events) — retargeting


---

# Web Storage (/docs/javascript/dom/storage)



# Web Storage [#web-storage]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

`localStorage` and `sessionStorage` provide synchronous key/value string storage per origin. Use them for small preferences — not for large datasets or secrets. Prefer IndexedDB for structured/offline data.

## 🔧 Core concepts [#-core-concepts]

* **`localStorage`**: persists across sessions until cleared.
* **`sessionStorage`**: per-tab session; survives reload, not new tabs (usually).
* **API**: `getItem`, `setItem`, `removeItem`, `clear`, `key(i)`, `length`.
* **Quota**: throws `QuotaExceededError` when full.
* **Events**: `storage` fires in *other* documents of the same origin on `localStorage` changes.
* **Only strings**: JSON-encode objects.

```js
localStorage.setItem("theme", "dark");
const theme = localStorage.getItem("theme");
```

## 💡 Examples [#-examples]

```js
const storage = {
  get(key, fallback = null) {
    try {
      const raw = localStorage.getItem(key);
      return raw == null ? fallback : JSON.parse(raw);
    } catch {
      return fallback;
    }
  },
  set(key, value) {
    localStorage.setItem(key, JSON.stringify(value));
  },
  remove(key) {
    localStorage.removeItem(key);
  },
};

storage.set("user", { id: 1, name: "Ada" });
const user = storage.get("user", {});

// Cross-tab sync
window.addEventListener("storage", (e) => {
  if (e.key === "theme") {
    applyTheme(e.newValue);
  }
});

// sessionStorage wizard draft
sessionStorage.setItem("draft", JSON.stringify(formState));

// Enumerate
for (let i = 0; i < localStorage.length; i++) {
  const k = localStorage.key(i);
  console.log(k, localStorage.getItem(k));
}
```

```js
try {
  localStorage.setItem("cache", bigString);
} catch (err) {
  if (err.name === "QuotaExceededError") {
    localStorage.removeItem("cache");
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Synchronous and blocking — avoid huge reads/writes on the main thread.
* Never store tokens/passwords in accessible storage without a clear threat model.
* Private mode / blocked storage can throw on access — wrap in try/catch.
* `storage` event does not fire in the writer’s document.
* Values are strings — forgetting `JSON.parse` yields subtle bugs.

## 🔗 Related [#-related]

* [window.md](/docs/javascript/dom/window) — window\.localStorage
* [events.md](/docs/javascript/dom/events) — storage event
* [../json.md](/docs/javascript/json) — serialize values
* [../error.md](/docs/javascript/error) — quota errors
* [navigation.md](/docs/javascript/dom/navigation) — session lifecycle
* [../objects.md](/docs/javascript/objects) — plain data shapes


---

# Window (/docs/javascript/dom/window)



# Window [#window]

*JavaScript DOM · Reference cheat sheet*

## 📋 Overview [#-overview]

`window` is the global object in browsers (`globalThis === window`). It exposes the viewport, timers, framing, storage entry points, and dialogs. Prefer feature-specific APIs (`document`, `location`, `fetch`) over legacy window methods when both exist.

## 🔧 Core concepts [#-core-concepts]

* **Global**: undeclared `var` / browser globals hang off `window`; modules don’t create globals.
* **Viewport**: `innerWidth`, `innerHeight`, `outerWidth`, `scrollX`, `scrollY`, `devicePixelRatio`.
* **Frames**: `parent`, `top`, `frames`, `frameElement`.
* **Timers**: `setTimeout`, `setInterval`, `requestAnimationFrame`, `requestIdleCallback`.
* **Dialogs**: `alert`, `confirm`, `prompt` (blocking — avoid in modern UX).
* **Open**: `window.open`, `close`, `focus` (popup rules apply).

```js
requestAnimationFrame(draw);
window.addEventListener("resize", onResize);
```

## 💡 Examples [#-examples]

```js
// Scroll helpers
window.scrollTo({ top: 0, behavior: "smooth" });
const y = window.scrollY;

// rAF loop
let raf;
function loop(t) {
  update(t);
  raf = requestAnimationFrame(loop);
}
raf = requestAnimationFrame(loop);
cancelAnimationFrame(raf);

// Match media
const dark = window.matchMedia("(prefers-color-scheme: dark)");
dark.addEventListener("change", (e) => {
  document.documentElement.dataset.theme = e.matches ? "dark" : "light";
});

// postMessage (cross-window)
otherWindow.postMessage({ type: "ping" }, "https://trusted.example");
window.addEventListener("message", (e) => {
  if (e.origin !== "https://trusted.example") return;
  console.log(e.data);
});

// Safe external open
const w = window.open("https://example.com", "_blank", "noopener,noreferrer");
```

```js
// globalThis for portable code
const g = globalThis;
g.addEventListener?.("offline", () => showBanner());

// Idle work when browser is quiet
requestIdleCallback?.((deadline) => {
  while (deadline.timeRemaining() > 0 && jobs.length) {
    jobs.shift()();
  }
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Popup blockers require `window.open` in direct user-gesture handlers.
* Always verify `event.origin` on `message` events.
* `innerWidth` includes scrollbars differently across engines — test layout.
* Blocking dialogs freeze the main thread and are suppressed in many contexts.
* In workers there is no `window` — use `self` / `globalThis`.

## 🔗 Related [#-related]

* [document\_methods.md](/docs/javascript/dom/document-methods) — document
* [navigation.md](/docs/javascript/dom/navigation) — location / history
* [screen.md](/docs/javascript/dom/screen) — screen metrics
* [position.md](/docs/javascript/dom/position) — scroll & geometry
* [events.md](/docs/javascript/dom/events) — window events
* [storage.md](/docs/javascript/dom/storage) — localStorage
* [../api.md](/docs/javascript/api) — timers & fetch globals
* [../fetch.md](/docs/javascript/fetch) — networking


---

# dotenv (/docs/javascript/dotenv)



# dotenv [#dotenv]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

In Node.js, configuration often lives in environment variables via `process.env`. The popular `dotenv` package loads a `.env` file into `process.env` at startup. Never commit secrets; use `.env.example` for templates.

```shellscript
npm install dotenv
```

## 🔧 Core concepts [#-core-concepts]

* **`process.env.KEY`**: always a string (or `undefined` if unset).
* **`dotenv.config()`**: reads `.env` from cwd by default; does not overwrite existing env vars.
* **`.env` syntax**: `KEY=value`, comments with `#`, optional quotes.
* **Precedence**: real environment (shell, CI, host) wins over `.env` unless you opt into override.
* **Validation**: check required keys early and exit with a clear error.

## 💡 Examples [#-examples]

```js
// CommonJS
require("dotenv").config();

// ESM (early in entry file)
import "dotenv/config";
// or
import dotenv from "dotenv";
dotenv.config({ path: ".env.local" });

const port = Number(process.env.PORT ?? "3000");
const dbUrl = process.env.DATABASE_URL;

if (!dbUrl) {
  console.error("Missing DATABASE_URL");
  process.exit(1);
}

// Optional override (use carefully)
dotenv.config({ override: true });

// Typed-ish helper
function requireEnv(name) {
  const v = process.env[name];
  if (v === undefined || v === "") {
    throw new Error(`Missing env: ${name}`);
  }
  return v;
}

const apiKey = requireEnv("API_KEY");
```

```ini
# .env
PORT=9000
DATABASE_URL=postgres://localhost:5432/app
# FEATURE_FLAG=true
```

## ⚠️ Pitfalls [#️-pitfalls]

* `process.env` values are strings: `"false"` is truthy; parse booleans/numbers explicitly.
* `dotenv` does not magically load in every worker/child — call config in each process entry.
* Do not rely on `.env` in production if the platform injects env vars (Render, Netlify, etc.).
* Avoid putting secrets in client bundles; `dotenv` is a Node/server concern.
* Empty `KEY=` sets `process.env.KEY` to `""`, not `undefined`.

## 🔗 Related [#-related]

* [process](/docs/javascript/process) — `process.env`, `argv`, `exit`
* [fs](/docs/javascript/fs) — reading config files manually
* [JSON](/docs/javascript/json) — config as JSON instead of `.env`
* [CommonJS modules](/docs/javascript/modules-commonjs) — `require("dotenv")`
* [ESM import/export](/docs/javascript/import-export) — `import "dotenv/config"`


---

# Encode / Decode (/docs/javascript/encode)



# Encode / Decode [#encode--decode]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

Encoding turns text into safe wire formats: URI components, percent-encoding, and Base64. Use the right API for path vs query vs full URI. Pair with `TextEncoder` for UTF-8 bytes.

## 🔧 Core concepts [#-core-concepts]

* **`encodeURI` / `decodeURI`**: encode a full URI; leaves `#`, `?`, `/`, etc.
* **`encodeURIComponent` / `decodeURIComponent`**: encode a single component (query values, path segments).
* **`URL` / `URLSearchParams`**: prefer structured URL building over manual concat.
* **Base64**: `btoa` / `atob` (Latin-1); use byte-safe helpers for UTF-8.
* **UTF-8 bytes**: `TextEncoder` / `TextDecoder`.

```js
encodeURIComponent("a b&c"); // a%20b%26c
decodeURIComponent("a%20b%26c"); // a b&c
```

## 💡 Examples [#-examples]

```js
const q = new URLSearchParams({ q: "café & tea", page: "1" });
console.log(q.toString()); // q=caf%C3%A9+%26+tea&page=1

const url = new URL("https://example.com/search");
url.searchParams.set("q", "hello world");
console.log(url.href);

// Path segment
const slug = encodeURIComponent("foo/bar"); // foo%2Fbar

// UTF-8 Base64
function utf8ToBase64(str) {
  const bytes = new TextEncoder().encode(str);
  let bin = "";
  for (const b of bytes) bin += String.fromCharCode(b);
  return btoa(bin);
}

function base64ToUtf8(b64) {
  const bin = atob(b64);
  const bytes = Uint8Array.from(bin, (c) => c.charCodeAt(0));
  return new TextDecoder().decode(bytes);
}

console.log(base64ToUtf8(utf8ToBase64("✓")));

// application/x-www-form-urlencoded
const body = new URLSearchParams({ email: "a@b.co", remember: "1" });
await fetch("/login", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body,
});
```

```js
// Wrong vs right for query values
const bad = "https://x.test/?q=" + encodeURI("a&b"); // & still breaks
const good = "https://x.test/?q=" + encodeURIComponent("a&b");
```

## ⚠️ Pitfalls [#️-pitfalls]

* Never use `encodeURI` for query parameter values — use `encodeURIComponent`.
* Double-encoding (`encode` then `encode` again) breaks servers.
* `decodeURIComponent` throws `URIError` on malformed sequences — wrap in try/catch.
* `+` in query strings often means space; `URLSearchParams` handles this.
* `btoa("✓")` throws — encode UTF-8 bytes first.

## 🔗 Related [#-related]

* [url.md](/docs/javascript/url) — URL and search params
* [fetch.md](/docs/javascript/fetch) — request bodies
* [strings.md](/docs/javascript/strings) — string ops
* [api.md](/docs/javascript/api) — TextEncoder / crypto
* [json.md](/docs/javascript/json) — JSON payloads


---

# Equality (/docs/javascript/equality)



# Equality [#equality]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

JavaScript has strict equality (`===` / `!==`), loose equality (`==` / `!=`) with coercion, and `Object.is` for SameValue semantics. Prefer `===` almost always; use `Object.is` for `NaN` and ±0 edge cases; avoid `==` except intentional nullish checks.

## 🔧 Core concepts [#-core-concepts]

| Op               | Rule                                              |
| ---------------- | ------------------------------------------------- |
| `===`            | Same type + value; no coercion; `NaN !== NaN`     |
| `==`             | Coerces then compares (complex rules)             |
| `Object.is(a,b)` | SameValue: `NaN` equals `NaN`; `-0` ≠ `+0`        |
| `SameValueZero`  | Used by `Map`/`Set`: `NaN` equals `NaN`, ±0 equal |

* **`null == undefined`** is `true&#x60;; &#x2A;*`null === undefined`** is `false`.
* **Objects**: equality is by reference, not deep content.

```js
1 === "1"; // false
1 == "1"; // true
Object.is(NaN, NaN); // true
```

## 💡 Examples [#-examples]

```js
// Prefer strict
if (status === 200) {
  /* ... */
}

// Intentional nullish (either)
if (value == null) {
  // value is null or undefined
}

// NaN checks
Number.isNaN(x); // preferred over x === NaN
Object.is(x, NaN);

// Zeros
+0 === -0; // true
Object.is(+0, -0); // false

// Objects
const a = { x: 1 };
const b = { x: 1 };
a === b; // false
a === a; // true

// Arrays / boxed
[] == false; // true (avoid!)
[1] == true; // false weirdness — never use == with objects

// Map keying uses SameValueZero
const m = new Map();
m.set(NaN, "yes");
m.get(NaN); // "yes"
```

```js
// Deep equality — use a library or structured approach
function shallowEq(a, b) {
  return Object.keys(a).length === Object.keys(b).length &&
    Object.keys(a).every((k) => a[k] === b[k]);
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `==` with mixed types is a footgun (`"" == 0`, `null == undefined`, arrays).
* `NaN === NaN` is false — use `Number.isNaN` / `Object.is`.
* Document / iframe boundaries: different `Object` constructors break `instanceof` and sometimes expectations.
* Floating point: `0.1 + 0.2 !== 0.3` — compare with epsilon, not `===`.

## 🔗 Related [#-related]

* [type\_coercion.md](/docs/javascript/type-coercion) — how `==` coerces
* [boolean.md](/docs/javascript/boolean) — truthiness
* [nullish\_coalescing.md](/docs/javascript/nullish-coalescing) — nullish ops
* [object / map](/docs/javascript/map) — SameValueZero keys
* [number.md](/docs/javascript/number) — NaN and floats


---

# Errors (/docs/javascript/error)



# Errors [#errors]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

Errors interrupt normal control flow. Use `try` / `catch` / `finally`, typed error classes, and rethrow carefully. Prefer throwing `Error` (or subclasses) over strings so stacks and `cause` work.

## 🔧 Core concepts [#-core-concepts]

* **Built-ins**: `Error`, `TypeError`, `RangeError`, `SyntaxError`, `URIError`, `AggregateError`.
* **Properties**: `name`, `message`, `stack`, `cause` (ES2022).
* **Throw**: `throw new Error("msg", \{ cause \})`.
* **Catch**: bind the error; optional binding omission in some engines for unused catches.
* **`finally`**: always runs (cleanup), even on return.
* **Async**: rejections surface at `await` or `.catch`.

```js
try {
  JSON.parse("{");
} catch (err) {
  console.error(err.name, err.message);
} finally {
  console.log("done");
}
```

## 💡 Examples [#-examples]

```js
class HttpError extends Error {
  constructor(status, message, options) {
    super(message, options);
    this.name = "HttpError";
    this.status = status;
  }
}

async function getJson(url) {
  try {
    const res = await fetch(url);
    if (!res.ok) {
      throw new HttpError(res.status, res.statusText);
    }
    return await res.json();
  } catch (err) {
    throw new Error(`getJson failed: ${url}`, { cause: err });
  }
}

// Narrowing
function isHttpError(e) {
  return e instanceof HttpError;
}

try {
  await getJson("/api");
} catch (e) {
  if (isHttpError(e) && e.status === 404) {
    console.warn("missing");
  } else {
    throw e; // rethrow unknown
  }
}

// AggregateError (Promise.any)
try {
  await Promise.any([Promise.reject("a"), Promise.reject("b")]);
} catch (e) {
  if (e instanceof AggregateError) {
    console.log(e.errors);
  }
}

// Optional catch binding (when unused)
try {
  risky();
} catch {
  /* ignore */
}
```

```js
// AbortError from fetch
const ac = new AbortController();
fetch(url, { signal: ac.signal }).catch((err) => {
  if (err.name === "AbortError") return;
  console.error(err);
});
ac.abort();
```

## ⚠️ Pitfalls [#️-pitfalls]

* Catching everything and swallowing errors hides bugs — rethrow unknowns.
* `throw "string"` loses stack traces — throw `Error` instances.
* `finally` can override a returned/thrown value if it returns or throws itself.
* Async errors outside `try` around `await` become unhandled rejections.
* `instanceof` fails across realms/iframes — check `name` as fallback.

## 🔗 Related [#-related]

* [promise.md](/docs/javascript/promise) — rejection handling
* [async.md](/docs/javascript/async) — await + try/catch
* [fetch.md](/docs/javascript/fetch) — HTTP failures
* [console.md](/docs/javascript/console) — logging errors
* [api.md](/docs/javascript/api) — AbortController


---

# Event Loop (/docs/javascript/event-loop)



# Event Loop [#event-loop]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

JavaScript runs on a single thread with an event loop that drains task queues. Understanding macrotasks vs microtasks explains Promise ordering, `setTimeout(0)`, UI updates, and why long sync work freezes the page.

## 🔧 Core concepts [#-core-concepts]

* **Call stack**: runs synchronous code to completion.
* **Macrotasks (tasks)**: `setTimeout`, `setInterval`, I/O, UI events, `MessageChannel`, `setImmediate` (Node).
* **Microtasks**: Promise reactions, `queueMicrotask`, `MutationObserver` callbacks.
* **Order**: after each task, the engine drains **all** microtasks before the next macrotask / render.
* **Rendering**: browsers may paint between tasks (not between microtasks).
* **Workers**: separate event loops / threads.

```js
console.log("a");
setTimeout(() => console.log("c"), 0);
Promise.resolve().then(() => console.log("b"));
// a, b, c
```

## 💡 Examples [#-examples]

```js
queueMicrotask(() => console.log("micro"));
Promise.resolve().then(() => console.log("then"));
setTimeout(() => console.log("timeout"), 0);
console.log("sync");
// sync → micro → then → timeout

// Microtask starvation risk
function flood() {
  Promise.resolve().then(flood);
}
// flood(); // never reaches next macrotask / paint

// Yield to the event loop
async function yieldToMain() {
  await new Promise((r) => setTimeout(r, 0));
}

async function processChunks(items) {
  for (const item of items) {
    work(item);
    await yieldToMain();
  }
}

// async function scheduling
async function demo() {
  console.log(1);
  await null; // microtask continuation
  console.log(2);
}
demo();
console.log(3);
// 1, 3, 2
```

```js
// Node: process.nextTick (microtask-like, before Promises historically)
// Prefer queueMicrotask / Promises for portable code
```

## ⚠️ Pitfalls [#️-pitfalls]

* `setTimeout(fn, 0)` is not “immediate” — it waits for the current task + microtasks + timer clamping.
* Infinite microtask chains block rendering and timers.
* Assuming Promise callbacks run in parallel — they are still sequential on one thread.
* Heavy sync work (JSON.parse huge data, tight loops) blocks everything — chunk or move to workers.
* Error in a microtask can surface differently than in a timer callback.

## 🔗 Related [#-related]

* [promise.md](/docs/javascript/promise) — microtask reactions
* [async.md](/docs/javascript/async) — async/await desugaring
* [timers.md](/docs/javascript/timers) — macrotask timers
* [web\_workers.md](/docs/javascript/web-workers) — off-main-thread
* [DOM/events.md](/docs/javascript/dom/events) — event tasks


---

# Events (/docs/javascript/events-node)



# Events [#events]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Node.js `EventEmitter` (`node:events`) is the pub/sub backbone for streams, servers, and many core APIs. Objects emit named events; listeners run when those events fire. Browser DOM events are different — see DOM Events for UI.

```js
import { EventEmitter } from "node:events";
```

## 🔧 Core concepts [#-core-concepts]

* **`on(event, listener)` / `addListener`**: register a lasting handler.
* **`once(event, listener)`**: run at most once, then remove.
* **`emit(event, ...args)`**: call listeners synchronously in registration order.
* **`off` / `removeListener` / `removeAllListeners`**: unsubscribe.
* **`prependListener`**: run before previously registered handlers.
* **Error event**: if `error` is emitted with no listeners, Node throws.
* **`EventEmitter` subclassing**: common pattern for custom components.

## 💡 Examples [#-examples]

```js
import { EventEmitter } from "node:events";

const bus = new EventEmitter();

bus.on("data", (chunk) => console.log("got", chunk));
bus.once("ready", () => console.log("ready once"));

bus.emit("ready");
bus.emit("ready"); // no-op for once
bus.emit("data", { n: 1 });

bus.off("data", handler); // need same function reference

class Job extends EventEmitter {
  start() {
    this.emit("start");
    try {
      // work…
      this.emit("done", { ok: true });
    } catch (err) {
      this.emit("error", err);
    }
  }
}

const job = new Job();
job.on("error", (err) => console.error(err));
job.start();
```

```js
import { once } from "node:events";
// Promise that resolves on next event
const [value] = await once(bus, "data");
```

## ⚠️ Pitfalls [#️-pitfalls]

* Listeners are sync: a slow handler blocks subsequent listeners and the emitter.
* Missing `error` listener can crash the process when `emit("error", err)` runs.
* Memory leaks: forgetting to `off` long-lived emitters (set `setMaxListeners` only after understanding why).
* Arrow vs bound methods: remove requires the same function reference you added.
* Do not confuse with DOM `EventTarget` — APIs differ (`addEventListener` vs `on`).

## 🔗 Related [#-related]

* [DOM Events](/docs/javascript/dom/events) — browser event model
* [Stream](/docs/javascript/stream) — streams extend EventEmitter patterns
* [Async](/docs/javascript/async) — `once()` promise helper
* [Promise](/docs/javascript/promise) — bridging events to promises
* [this keyword](/docs/javascript/this-keyword) — listener `this` binding


---

# Examples (/docs/javascript/examples)



# Examples [#examples]

JavaScript notes in **Examples**.


---

# Array Pipeline (/docs/javascript/examples/array-pipeline)



# Array Pipeline [#array-pipeline]

*Javascript · Example / how-to*

***

## 📋 Overview [#-overview]

Transform collections with a readable `filter` → `map` → `reduce` pipeline instead of nested loops.

## 🔧 Core concepts [#-core-concepts]

| Piece        | Role                          |
| ------------ | ----------------------------- |
| `filter`     | Keep matching items           |
| `map`        | Project shape                 |
| `reduce`     | Aggregate to one value        |
| Immutability | Prefer new arrays over mutate |

## 💡 Examples [#-examples]

**array\_pipeline.js:**

```javascript
const orders = [
  { id: 1, status: "paid", total: 42.5, tags: ["books"] },
  { id: 2, status: "pending", total: 10, tags: ["toys"] },
  { id: 3, status: "paid", total: 19.99, tags: ["books", "sale"] },
  { id: 4, status: "paid", total: 5, tags: ["sale"] },
];

const paidBookRevenue = orders
  .filter((o) => o.status === "paid")
  .filter((o) => o.tags.includes("books"))
  .map((o) => ({ id: o.id, total: o.total }))
  .reduce((sum, o) => sum + o.total, 0);

console.log(paidBookRevenue); // 62.49

const byTag = orders
  .flatMap((o) => o.tags.map((tag) => [tag, o.total]))
  .reduce((acc, [tag, total]) => {
    acc[tag] = (acc[tag] ?? 0) + total;
    return acc;
  }, {});

console.log(byTag);
```

**Readable helpers:**

```javascript
const isPaid = (o) => o.status === "paid";
const hasTag = (tag) => (o) => o.tags.includes(tag);

const total = orders.filter(isPaid).filter(hasTag("sale")).reduce((s, o) => s + o.total, 0);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Chaining many `filter`/`map` passes over large arrays — combine when hot.
* `reduce` without an initial value fails on empty arrays for objects.
* Mutating inside `map` surprises callers — return new objects.

## 🔗 Related [#-related]

* [Fetch JSON](/docs/javascript/examples/fetch-json)
* [Debounce input](/docs/javascript/examples/debounce-input)


---

# Debounce Input (/docs/javascript/examples/debounce-input)



# Debounce Input [#debounce-input]

*Javascript · Example / how-to*

***

## 📋 Overview [#-overview]

Debounce a search input so filtering runs after the user pauses typing, not on every keystroke.

## 🔧 Core concepts [#-core-concepts]

| Piece                         | Role                     |
| ----------------------------- | ------------------------ |
| Debounce                      | Delay until quiet period |
| `setTimeout` / `clearTimeout` | Schedule and cancel      |
| `input` event                 | Live typing              |
| Closure                       | Hold timer id            |

## 💡 Examples [#-examples]

**debounce\_input.js:**

```javascript
function debounce(fn, waitMs = 300) {
  let timer;
  return function debounced(...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), waitMs);
  };
}

const input = document.querySelector("#search");
const status = document.querySelector("#status");
const items = ["Apple", "Apricot", "Banana", "Blueberry", "Cherry"];

function filterItems(query) {
  const q = query.trim().toLowerCase();
  const matches = items.filter((item) => item.toLowerCase().includes(q));
  status.textContent = q
    ? `Matches: ${matches.join(", ") || "(none)"}`
    : "Type to filter…";
}

input.addEventListener(
  "input",
  debounce((event) => filterItems(event.target.value), 300),
);
```

**Cancel on blur (optional):**

```javascript
function debounceCancelable(fn, waitMs = 300) {
  let timer;
  const wrapped = (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), waitMs);
  };
  wrapped.cancel = () => clearTimeout(timer);
  return wrapped;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Debounce delays the last call; throttle limits rate — pick the right one.
* Always `clearTimeout` before scheduling again or timers stack.
* In SPAs, cancel pending timers on unmount to avoid setState-after-unmount.

## 🔗 Related [#-related]

* [DOM todo](/docs/javascript/examples/dom-todo)
* [LocalStorage prefs](/docs/javascript/examples/localstorage-prefs)


---

# DOM Todo (/docs/javascript/examples/dom-todo)



# DOM Todo [#dom-todo]

*Javascript · Example / how-to*

***

## 📋 Overview [#-overview]

Build a small todo list with vanilla DOM: add items, toggle done, and remove rows without a framework.

## 🔧 Core concepts [#-core-concepts]

| Piece           | Role                   |
| --------------- | ---------------------- |
| `querySelector` | Find form / list roots |
| `createElement` | Build list items       |
| Event listeners | Submit, click, change  |
| `dataset`       | Store item ids         |

## 💡 Examples [#-examples]

**index.html (snippet):**

```html
<form id="todo-form">
  <input id="todo-input" name="title" required placeholder="New task" />
  <button type="submit">Add</button>
</form>
<ul id="todo-list"></ul>
```

**dom\_todo.js:**

```javascript
const form = document.querySelector("#todo-form");
const input = document.querySelector("#todo-input");
const list = document.querySelector("#todo-list");

let nextId = 1;

function createItem(title) {
  const id = String(nextId++);
  const li = document.createElement("li");
  li.dataset.id = id;

  const label = document.createElement("label");
  const checkbox = document.createElement("input");
  checkbox.type = "checkbox";
  checkbox.addEventListener("change", () => {
    li.classList.toggle("done", checkbox.checked);
  });

  const text = document.createElement("span");
  text.textContent = title;

  const remove = document.createElement("button");
  remove.type = "button";
  remove.textContent = "Remove";
  remove.addEventListener("click", () => li.remove());

  label.append(checkbox, text);
  li.append(label, remove);
  return li;
}

form.addEventListener("submit", (event) => {
  event.preventDefault();
  const title = input.value.trim();
  if (!title) return;
  list.append(createItem(title));
  input.value = "";
  input.focus();
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting `preventDefault` reloads the page on submit.
* Building HTML with `innerHTML` + user text risks XSS — use `textContent`.
* Attaching listeners only on the form/list (delegation) scales better for many items.

## 🔗 Related [#-related]

* [Debounce input](/docs/javascript/examples/debounce-input)
* [LocalStorage prefs](/docs/javascript/examples/localstorage-prefs)


---

# Fetch JSON (/docs/javascript/examples/fetch-json)



# Fetch JSON [#fetch-json]

*Javascript · Example / how-to*

***

## 📋 Overview [#-overview]

Load JSON from an API with `fetch`, handle HTTP errors, and render a simple list in the DOM.

## 🔧 Core concepts [#-core-concepts]

| Piece             | Role              |
| ----------------- | ----------------- |
| `fetch`           | Network request   |
| `response.ok`     | Detect non-2xx    |
| `response.json()` | Parse body        |
| `async` / `await` | Linear async flow |

## 💡 Examples [#-examples]

**fetch\_json.js:**

```javascript
async function fetchJson(url, options = {}) {
  const response = await fetch(url, {
    headers: { Accept: "application/json", ...options.headers },
    ...options,
  });
  if (!response.ok) {
    throw new Error(`HTTP ${response.status} for ${url}`);
  }
  return response.json();
}

async function loadPosts(target) {
  target.textContent = "Loading…";
  try {
    const posts = await fetchJson(
      "https://jsonplaceholder.typicode.com/posts?_limit=5",
    );
    target.replaceChildren();
    for (const post of posts) {
      const li = document.createElement("li");
      li.textContent = post.title;
      target.append(li);
    }
  } catch (err) {
    target.textContent = `Failed: ${err.message}`;
  }
}

const list = document.querySelector("#posts");
loadPosts(list);
```

**Abort on unmount / navigation:**

```javascript
const controller = new AbortController();
const data = await fetchJson(url, { signal: controller.signal });
// later: controller.abort();
```

## ⚠️ Pitfalls [#️-pitfalls]

* `fetch` only rejects on network failure — check `response.ok` yourself.
* Calling `.json()` twice on the same body fails; clone or read once.
* CORS blocks browser calls to many APIs — use a proxy or same-origin route.

## 🔗 Related [#-related]

* [Array pipeline](/docs/javascript/examples/array-pipeline)
* [DOM todo](/docs/javascript/examples/dom-todo)


---

# LocalStorage Prefs (/docs/javascript/examples/localstorage-prefs)



# LocalStorage Prefs [#localstorage-prefs]

*Javascript · Example / how-to*

***

## 📋 Overview [#-overview]

Persist simple user preferences (theme, density) in `localStorage` with JSON encode/decode and safe defaults.

## 🔧 Core concepts [#-core-concepts]

| Piece                      | Role                         |
| -------------------------- | ---------------------------- |
| `localStorage`             | Per-origin key/value strings |
| `JSON.stringify` / `parse` | Structured prefs             |
| Defaults merge             | Survive missing keys         |
| `storage` event            | Sync across tabs             |

## 💡 Examples [#-examples]

**localstorage\_prefs.js:**

```javascript
const STORAGE_KEY = "app.prefs.v1";

const DEFAULT_PREFS = {
  theme: "system",
  density: "comfortable",
};

function loadPrefs() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (!raw) return { ...DEFAULT_PREFS };
    const parsed = JSON.parse(raw);
    return { ...DEFAULT_PREFS, ...parsed };
  } catch {
    return { ...DEFAULT_PREFS };
  }
}

function savePrefs(prefs) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(prefs));
}

function applyTheme(theme) {
  const resolved =
    theme === "system"
      ? window.matchMedia("(prefers-color-scheme: dark)").matches
        ? "dark"
        : "light"
      : theme;
  document.documentElement.dataset.theme = resolved;
}

const prefs = loadPrefs();
applyTheme(prefs.theme);

document.querySelector("#theme").value = prefs.theme;
document.querySelector("#theme").addEventListener("change", (event) => {
  prefs.theme = event.target.value;
  savePrefs(prefs);
  applyTheme(prefs.theme);
});

window.addEventListener("storage", (event) => {
  if (event.key !== STORAGE_KEY || !event.newValue) return;
  const next = { ...DEFAULT_PREFS, ...JSON.parse(event.newValue) };
  applyTheme(next.theme);
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* `localStorage` is sync and string-only — always JSON round-trip objects.
* Quota / private mode can throw — wrap reads/writes in `try/catch`.
* Do not store secrets; anything in `localStorage` is readable by XSS.

## 🔗 Related [#-related]

* [DOM todo](/docs/javascript/examples/dom-todo)
* [Debounce input](/docs/javascript/examples/debounce-input)


---

# Fetch (/docs/javascript/fetch)



# Fetch [#fetch]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`fetch` performs HTTP requests and returns a Promise of `Response`. It only rejects on network failure or abort — HTTP 4xx/5xx still resolve. Always check `response.ok` or `status`.

## 🔧 Core concepts [#-core-concepts]

* **Call**: `fetch(input, init?)` → `Promise<Response>`.
* **Init**: `method`, `headers`, `body`, `credentials`, `signal`, `cache`, `redirect`, `mode`.
* **Body helpers**: `res.json()`, `res.text()`, `res.blob()`, `res.arrayBuffer()`, `res.formData()`.
* **Request body**: string, `Blob`, `FormData`, `URLSearchParams`, `ReadableStream`, `ArrayBuffer`.
* **Abort**: pass `AbortSignal` via `signal`.

```js
const res = await fetch("/api/items");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
```

## 💡 Examples [#-examples]

```js
// JSON POST
async function createUser(user) {
  const res = await fetch("/api/users", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Accept: "application/json",
    },
    body: JSON.stringify(user),
  });
  if (!res.ok) {
    const err = await res.text();
    throw new Error(err || res.statusText);
  }
  return res.json();
}

// Query string
const url = new URL("/search", location.origin);
url.searchParams.set("q", "js");
const list = await fetch(url).then((r) => r.json());

// Timeout via AbortSignal
async function fetchWithTimeout(resource, ms, options = {}) {
  const signal = AbortSignal.timeout(ms);
  return fetch(resource, { ...options, signal });
}

// Credentials (cookies)
await fetch("/api/me", { credentials: "include" });

// Upload FormData
const fd = new FormData();
fd.append("file", fileInput.files[0]);
fd.append("title", "doc");
await fetch("/upload", { method: "POST", body: fd });

// Read headers
const res = await fetch("/api");
console.log(res.headers.get("content-type"));
```

```js
// Stream response body
const res = await fetch("/large.bin");
const reader = res.body.getReader();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  console.log("chunk", value.byteLength);
}

// Parallel requests
const [a, b] = await Promise.all([
  fetch("/a").then((r) => r.json()),
  fetch("/b").then((r) => r.json()),
]);
```

## ⚠️ Pitfalls [#️-pitfalls]

* `fetch` does not throw on 404/500 — check `ok` / `status`.
* Body can be consumed once — clone with `res.clone()` if needed twice.
* Default `credentials` is `"same-origin"`; cross-site cookies need `"include"` + CORS.
* Setting `Content-Type` manually on `FormData` breaks the multipart boundary.
* Opaque responses (`mode: "no-cors"`) hide status and body.

## 🔗 Related [#-related]

* [promise.md](/docs/javascript/promise) — Promise combinators
* [async.md](/docs/javascript/async) — async/await
* [json.md](/docs/javascript/json) — JSON bodies
* [url.md](/docs/javascript/url) — URL building
* [encode.md](/docs/javascript/encode) — form encoding
* [error.md](/docs/javascript/error) — error wrapping
* [api.md](/docs/javascript/api) — AbortSignal
* [DOM/form.md](/docs/javascript/dom/form) — FormData from forms


---

# for...of (/docs/javascript/for-of)



# for...of [#forof]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`for...of` iterates values from any iterable (`Array`, `String`, `Map`, `Set`, generators, DOM collections that are iterable). Prefer it over index loops when you need values, not indices.

## 🔧 Core concepts [#-core-concepts]

* **Syntax**: `for (const item of iterable) \{ ... \}`.
* **Bindings**: `const` / `let` / destructuring per iteration.
* **Control**: `break`, `continue`, `return` (from enclosing function).
* **Async**: `for await (const x of asyncIterable)`.
* **vs `for...in`**: `in` enumerates keys; `of` yields values.

```js
for (const n of [10, 20, 30]) {
  console.log(n);
}
```

## 💡 Examples [#-examples]

```js
// Entries with index
for (const [i, v] of ["a", "b"].entries()) {
  console.log(i, v);
}

// Strings (Unicode code points with for...of)
for (const ch of "A🙂B") {
  console.log(ch);
}

// Map / Set
const m = new Map([["x", 1], ["y", 2]]);
for (const [k, v] of m) console.log(k, v);

for (const v of new Set([1, 1, 2])) console.log(v);

// Destructure objects in arrays
const rows = [{ id: 1 }, { id: 2 }];
for (const { id } of rows) console.log(id);

// early exit
for (const n of nums) {
  if (n < 0) break;
}

// NodeList (modern browsers — iterable)
for (const el of document.querySelectorAll("li")) {
  el.classList.add("ready");
}

// Async iterable
async function consume(stream) {
  for await (const chunk of stream) {
    console.log(chunk);
  }
}
```

```js
// Generator source
function* range(n) {
  for (let i = 0; i < n; i++) yield i;
}
for (const i of range(3)) console.log(i); // 0 1 2
```

## ⚠️ Pitfalls [#️-pitfalls]

* Do not use `for...in` on arrays when you want values — it yields keys as strings and enumerable prototype props.
* Closing iterators: `break` calls `return()` on the iterator if present (important for generators with `finally`).
* `for await...of` only works in async functions / modules with top-level await.
* Mutating a collection while iterating can skip items or throw — iterate a snapshot (`[...list]`).

## 🔗 Related [#-related]

* [iteration.md](/docs/javascript/iteration) — all loop styles
* [iterator.md](/docs/javascript/iterator) — iterable protocol
* [arrays.md](/docs/javascript/arrays) — array helpers
* [map.md](/docs/javascript/map) — Map iteration
* [set.md](/docs/javascript/set) — Set iteration
* [async.md](/docs/javascript/async) — for await...of
* [while.md](/docs/javascript/while) — while / do...while


---

# Freeze & Seal (/docs/javascript/freeze-seal)



# Freeze & Seal [#freeze--seal]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`Object.freeze`, `Object.seal`, and `Object.preventExtensions` progressively lock objects against extension and mutation. They are shallow. For true immutability in apps, combine with conventions, structuredClone, or immutable libraries — and know what each level allows.

## 🔧 Core concepts [#-core-concepts]

| Method              | Add props | Delete | Reassign values | Reconfigure            |
| ------------------- | --------- | ------ | --------------- | ---------------------- |
| `preventExtensions` | ✗         | ✓\*    | ✓               | ✓                      |
| `seal`              | ✗         | ✗      | ✓               | ✗ (configurable false) |
| `freeze`            | ✗         | ✗      | ✗               | ✗                      |

\*existing configurable props can still be deleted if not sealed.

* **Checks**: `Object.isFrozen`, `isSealed`, `isExtensible`.
* **Strict mode**: failed mutations throw `TypeError`; sloppy mode fails silently.
* **Shallow**: nested objects remain mutable unless frozen too.

```js
const cfg = Object.freeze({ theme: "dark", nested: { a: 1 } });
cfg.theme = "light"; // ignored / TypeError
cfg.nested.a = 2; // still works — shallow!
```

## 💡 Examples [#-examples]

```js
"use strict";

const sealed = Object.seal({ x: 1 });
sealed.x = 2; // OK
// sealed.y = 3; // TypeError
// delete sealed.x; // TypeError

const frozen = Object.freeze({ x: 1 });
// frozen.x = 2; // TypeError

Object.preventExtensions(arrLike);
// arrLike.newProp = 1; // TypeError

// Deep freeze (simple)
function deepFreeze(obj) {
  Object.freeze(obj);
  for (const value of Object.values(obj)) {
    if (value && typeof value === "object" && !Object.isFrozen(value)) {
      deepFreeze(value);
    }
  }
  return obj;
}

// Constants pattern
const ROUTES = Object.freeze({
  HOME: "/",
  ABOUT: "/about",
});

// Arrays
const list = Object.freeze([1, 2, 3]);
// list.push(4); // TypeError
```

```js
// Copy then freeze
const next = Object.freeze({ ...state, count: state.count + 1 });
```

## ⚠️ Pitfalls [#️-pitfalls]

* Shallow freeze is the #1 surprise — nested mutation still works.
* Freezing does not make values deeply immutable or protect against Proxy targets specially.
* `const` ≠ immutable — only rebinding is blocked; freeze the object too.
* Frozen arrays reject mutator methods; some libraries assume extensible objects.
* Cannot unfreeze — make a new object instead.

## 🔗 Related [#-related]

* [objects.md](/docs/javascript/objects) — property descriptors
* [strict\_mode.md](/docs/javascript/strict-mode) — TypeError on mutate
* [structured\_clone.md](/docs/javascript/structured-clone) — deep copy
* [proxy\_reflect.md](/docs/javascript/proxy-reflect) — deeper control
* [spread\_rest.md](/docs/javascript/spread-rest) — immutable updates


---

# fs (/docs/javascript/fs)



# fs [#fs]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Node.js filesystem APIs live in `node:fs`. Prefer `node:fs/promises` for async/await. Sync methods (`readFileSync`) block the event loop — fine for CLIs/startup, risky in servers.

```js
import fs from "node:fs/promises";
import { readFileSync } from "node:fs";
```

## 🔧 Core concepts [#-core-concepts]

* **`readFile(path, encoding?)`**: returns `Buffer` by default; pass `"utf8"` for a string.
* **`writeFile(path, data, options?)`**: creates/overwrites; `\{ flag: "a" \}` to append.
* **`mkdir(path, \{ recursive: true \})`**: create nested directories.
* **`readdir(path, \{ withFileTypes: true \})`**: list entries; Dirent has `isFile()` / `isDirectory()`.
* **`rm(path, \{ recursive, force \})`**: delete files or trees (replaces older `rmdir`/`unlink` combos).
* **Sync vs async**: `*Sync` blocks; promises/`fs.callbacks` do not.

## 💡 Examples [#-examples]

```js
import fs from "node:fs/promises";
import path from "node:path";

const text = await fs.readFile("notes.txt", "utf8");
await fs.writeFile("out.txt", text, "utf8");

await fs.mkdir(path.join("data", "cache"), { recursive: true });

const entries = await fs.readdir("data", { withFileTypes: true });
for (const ent of entries) {
  console.log(ent.name, ent.isDirectory() ? "dir" : "file");
}

await fs.rm("tmp/build", { recursive: true, force: true });

// Copy / rename
await fs.copyFile("a.json", "b.json");
await fs.rename("b.json", "c.json");

// Sync (scripts / one-shot tools)
import { readFileSync, writeFileSync } from "node:fs";
const cfg = readFileSync("config.json", "utf8");
writeFileSync("config.bak.json", cfg);
```

```js
// Ensure parent dir before write
async function writeSafe(file, data) {
  await fs.mkdir(path.dirname(file), { recursive: true });
  await fs.writeFile(file, data, "utf8");
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting encoding yields a `Buffer`, not a string.
* `writeFile` truncates by default — use append flag or read-modify-write carefully.
* `readdir` without `withFileTypes` returns names only; you need `stat` for type.
* Race conditions: check-then-write can fail; prefer `wx` flag or atomic rename patterns.
* Sync APIs in request handlers stall other connections.

## 🔗 Related [#-related]

* [Path](/docs/javascript/path) — join / resolve paths safely
* [Async](/docs/javascript/async) — async/await with promises
* [Promise](/docs/javascript/promise) — promise basics
* [Buffer](/docs/javascript/buffer) — binary file contents
* [JSON](/docs/javascript/json) — parse config after `readFile`
* [Stream](/docs/javascript/stream) — large files without loading all


---

# Functions (/docs/javascript/functions)



# Functions [#functions]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Functions are first-class values: declare them, pass them, return them, and store them. Prefer `function` declarations for hoisted named APIs, arrow functions for short callbacks, and methods for object behavior. Modern JS also supports default parameters, rest parameters, and concise bodies.

## 🔧 Core concepts [#-core-concepts]

* **Declaration**: `function name() \{\}` — hoisted (name available in whole scope).
* **Expression**: `const f = function() \{\}` / `const f = () => \{\}` — not hoisted as a binding.
* **Arrow**: lexical `this`, no `arguments`, no `new`, no `prototype`.
* **Defaults**: `function f(a = 1, b = a + 1) \{\}` — evaluated left-to-right when omitted/`undefined`.
* **Rest**: `function f(...args) \{\}` — gathers remaining args into an array.
* **Return**: explicit `return`; arrow concise body returns the expression.
* **IIFE**: `(function () \{ /* private scope */ \})();`

```js
function add(a, b = 0) {
  return a + b;
}
const double = (n) => n * 2;
```

## 💡 Examples [#-examples]

```js
// Named declaration
function greet(name = "world") {
  return `Hello, ${name}`;
}

// Rest + defaults
function sum(first = 0, ...rest) {
  return rest.reduce((a, b) => a + b, first);
}
sum(1, 2, 3); // 6

// Higher-order
function once(fn) {
  let called = false;
  let result;
  return function (...args) {
    if (!called) {
      called = true;
      result = fn.apply(this, args);
    }
    return result;
  };
}

// Method shorthand
const api = {
  base: "/v1",
  get(path) {
    return fetch(this.base + path);
  },
};

// Arrow keeps outer this
class Timer {
  constructor() {
    this.ticks = 0;
  }
  start() {
    setInterval(() => {
      this.ticks += 1;
    }, 1000);
  }
}

// arguments vs rest
function legacy() {
  return Array.from(arguments);
}
const modern = (...args) => args;
```

```js
// Early return / guard clauses
function parseId(raw) {
  if (raw == null) return null;
  const n = Number(raw);
  return Number.isFinite(n) ? n : null;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Arrow functions are not constructors — `new (() => \{\})` throws.
* Arrow `this` is lexical; do not use for object methods that need dynamic `this`.
* Default params only trigger on `undefined`, not `null`.
* Excess arguments are ignored unless you use rest/`arguments`.
* Function declarations inside blocks have historically inconsistent hoisting — prefer `const` expressions in blocks.

## 🔗 Related [#-related]

* [closures.md](/docs/javascript/closures) — lexical capture
* [this\_keyword.md](/docs/javascript/this-keyword) — call-site `this`
* [destructuring.md](/docs/javascript/destructuring) — param patterns
* [spread\_rest.md](/docs/javascript/spread-rest) — rest args
* [arrow / async](/docs/javascript/async) — async functions
* [oop.md](/docs/javascript/oop) — methods & classes


---

# Generators (/docs/javascript/generators)



# Generators [#generators]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Generator functions (`function*`) pause with `yield` and resume later, producing an iterator. They implement the iterable protocol, enable lazy sequences, custom iteration, and cooperative async flows (often via `async function*` for async iterables).

## 🔧 Core concepts [#-core-concepts]

* **Define**: `function* gen() \{ yield 1; \}`.
* **Iterator**: `const it = gen()` → `\{ next, return, throw \}`.
* **`next(value)`**: resumes; argument becomes the result of the current `yield`.
* **`yield*`**: delegate to another iterable/generator.
* **Done**: `\{ value, done: true \}` after `return` or end.
* **Async**: `async function*` + `for await...of`.

```js
function* count(n) {
  for (let i = 0; i < n; i++) yield i;
}
[...count(3)]; // [0, 1, 2]
```

## 💡 Examples [#-examples]

```js
function* idMaker() {
  let id = 1;
  while (true) yield id++;
}
const ids = idMaker();
ids.next().value; // 1
ids.next().value; // 2

// Two-way communication
function* quiz() {
  const name = yield "What is your name?";
  return `Hello, ${name}`;
}
const q = quiz();
q.next(); // { value: "What is your name?", done: false }
q.next("Ada"); // { value: "Hello, Ada", done: true }

// yield*
function* a() {
  yield 1;
  yield* [2, 3];
  yield 4;
}

// Lazy infinite filter
function* filter(iterable, pred) {
  for (const x of iterable) if (pred(x)) yield x;
}

// Async generator
async function* streamLines(readable) {
  for await (const chunk of readable) {
    yield* String(chunk).split("\n");
  }
}

for await (const line of streamLines(res.body)) {
  console.log(line);
}
```

```js
// Early cleanup
function* withResource() {
  try {
    yield "open";
  } finally {
    console.log("cleanup");
  }
}
const r = withResource();
r.next();
r.return(); // runs finally
```

## ⚠️ Pitfalls [#️-pitfalls]

* Generators are paused, not multithreaded — still single-threaded JS.
* Forgetting `*` makes a normal function that returns a generator object only if you call another generator.
* `yield` is invalid in non-generator callbacks (e.g. inside `.map` callback) — extract a generator helper.
* Infinite generators need care with `[...gen()]` — it never finishes.
* Mixing `throw` into generators requires handling inside the generator body.

## 🔗 Related [#-related]

* [iterator.md](/docs/javascript/iterator) — iterator protocol
* [iteration.md](/docs/javascript/iteration) — for...of
* [async.md](/docs/javascript/async) — async iteration
* [event\_loop.md](/docs/javascript/event-loop) — scheduling
* [arrays.md](/docs/javascript/arrays) — materializing with spread


---

# Getting Started with JavaScript (/docs/javascript/getting-started)



# Getting Started with JavaScript [#getting-started-with-javascript]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

JavaScript (JS) is the language of the web browser and a popular choice on servers via Node.js. You write `.js` (or `.mjs`) files, or run snippets in browser DevTools / Node’s REPL.

## 🔧 Core concepts [#-core-concepts]

| Idea            | Meaning                                       |
| --------------- | --------------------------------------------- |
| ECMAScript (ES) | The language standard JS implements           |
| Browser runtime | JS + DOM + Web APIs                           |
| Node.js         | JS outside the browser (files, servers, CLIs) |
| Engine          | V8, SpiderMonkey, etc. execute your code      |
| Module          | Reusable file using `import` / `export`       |

**Ways to try JS:** browser console (F12), Node (`node`), or a simple HTML file with a `<script>` tag.

## 💡 Examples [#-examples]

**Check Node version:**

```shellscript
node --version
```

**REPL one-liner:**

```shellscript
node
```

```js
> console.log("Hello")
Hello
> 2 + 2
4
```

**Script file (`hello.js`):**

```js
console.log("Hello from Node");
```

```shellscript
node hello.js
```

**In the browser (inline):**

```html
<!DOCTYPE html>
<html>
  <body>
    <script>
      console.log("Hello from the browser");
    </script>
  </body>
</html>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Browser JS and Node share the language but not all APIs (`document` vs `fs`).
* Old tutorials use `var` everywhere — prefer `let` / `const`.
* Forgetting to open the console makes `console.log` look like “nothing happened.”
* File protocol + modules can be awkward; use a tiny local server when learning modules.

## 🔗 Related [#-related]

* [hello\_world.md](/docs/javascript/hello-world)
* [variables\_let\_const.md](/docs/javascript/variables-let-const)
* [comments.md](/docs/javascript/comments)
* [typeof\_basics.md](/docs/javascript/typeof-basics)


---

# Glossary (/docs/javascript/glossary)



# Glossary [#glossary]

*Javascript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Alphabetical glossary of core JavaScript terms spanning values, functions, async flow, objects, and browser/runtime APIs.

## 🔧 Core concepts [#-core-concepts]

| Term              | Definition                                                                       |
| ----------------- | -------------------------------------------------------------------------------- |
| Array             | An ordered, indexable collection of values with array methods.                   |
| Async/await       | Syntax that pauses an async function until a Promise settles.                    |
| BigInt            | An integer type for values beyond `Number.MAX_SAFE_INTEGER`.                     |
| Boolean           | A primitive that is either `true` or `false`.                                    |
| Callback          | A function passed to another function to run later.                              |
| Closure           | A function that retains access to variables from its outer scope.                |
| Coercion          | Automatic or explicit conversion of a value from one type to another.            |
| Destructuring     | Syntax that unpacks values from arrays or properties from objects.               |
| Event loop        | The runtime mechanism that schedules macrotasks and microtasks.                  |
| Fetch             | The standard API for making HTTP requests that returns a Promise.                |
| Function          | A callable object that executes a block of code with parameters.                 |
| Generator         | A function using `function*` and `yield` that produces an iterator.              |
| Hoisting          | Moving declarations to the top of their scope during compilation.                |
| IIFE              | Immediately Invoked Function Expression that runs as soon as it is defined.      |
| Iterable          | An object that implements `[Symbol.iterator]` and can be looped with `for...of`. |
| JSON              | A text data format and global object for parse/stringify.                        |
| Map               | A collection of key–value pairs that preserves insertion order.                  |
| Module            | A file with its own scope that exports and imports bindings.                     |
| Null              | A primitive representing intentional absence of an object value.                 |
| Object            | A collection of named properties; almost everything non-primitive is one.        |
| Optional chaining | The `?.` operator that short-circuits when a reference is nullish.               |
| Promise           | An object representing a future success or failure of an async operation.        |
| Prototype         | The object linked for inheritance lookups via the prototype chain.               |
| Proxy             | An object that intercepts fundamental operations on another object.              |
| Scope             | The region of code where a binding is visible.                                   |
| Set               | A collection of unique values.                                                   |
| Spread            | The `...` syntax that expands iterables or object properties.                    |
| Strict mode       | A restricted JavaScript variant that catches silent errors.                      |
| Symbol            | A unique, immutable primitive often used as non-colliding property keys.         |
| Template literal  | A string delimited by backticks that supports interpolation and multiline text.  |
| This              | A binding whose value depends on how a function is called.                       |
| Undefined         | A primitive meaning a variable has been declared but not assigned.               |
| WeakMap           | A Map-like collection whose keys are weakly held objects.                        |

## 💡 Examples [#-examples]

**Closure and destructuring:**

```js
function makeCounter() {
  let n = 0;
  return () => ++n;
}
const { length } = [1, 2, 3];
```

**Promise with async/await:**

```js
async function loadUser(id) {
  const res = await fetch(`/api/users/${id}`);
  if (!res.ok) throw new Error("failed");
  return res.json();
}
```

**Optional chaining and nullish coalescing:**

```js
const name = user?.profile?.name ?? "Anonymous";
```

## ⚠️ Pitfalls [#️-pitfalls]

* Confusing **null** (intentional empty) with **undefined** (missing value).
* Mixing &#x2A;*==*&#x2A; coercion equality with &#x2A;*===** strict equality.
* Assuming **this** always means the enclosing object — it depends on call style.
* Treating **Map** like a plain **Object** — keys and iteration differ.
* Equating **callback** hell with **Promise** chains — both are async, different control styles.

## 🔗 Related [#-related]

* [closures](/docs/javascript/closures)
* [promise](/docs/javascript/promise)
* [async](/docs/javascript/async)
* [prototypes](/docs/javascript/prototypes)
* [destructuring](/docs/javascript/destructuring)
* [event\_loop](/docs/javascript/event-loop)


---

# Hello World (/docs/javascript/hello-world)



# Hello World [#hello-world]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Hello World confirms your JS environment works. The usual first call is `console.log`, which writes to the browser console or the terminal (Node).

## 🔧 Core concepts [#-core-concepts]

| Piece              | Role                                                        |
| ------------------ | ----------------------------------------------------------- |
| `console.log(...)` | Print values for humans / debugging                         |
| String literal     | `"text"` or `'text'` or `` `text` ``                        |
| Statement          | An instruction, often ending with `;` (ASI may insert them) |
| Script             | Code loaded by Node or a browser                            |

Semicolons are recommended for beginners even though Automatic Semicolon Insertion exists.

## 💡 Examples [#-examples]

**Node script:**

```js
console.log("Hello, World!");
```

```shellscript
node hello.js
```

**Multiple values:**

```js
const name = "Ada";
console.log("Hello,", name);
console.log(`Hello, ${name}!`);
```

**Browser alert (UI, not for real apps):**

```js
alert("Hello, World!");
```

**Log different types:**

```js
console.log(42);
console.log(true);
console.log({ ok: true });
console.log(["a", "b"]);
```

## ⚠️ Pitfalls [#️-pitfalls]

* In the browser, look at the **Console** tab — not the page body — for `console.log`.
* `alert` blocks the UI; use it sparingly while learning.
* Smart quotes from documents break string literals.
* Running TypeScript (`.ts`) needs a toolchain; plain Hello World should be `.js`.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/javascript/getting-started)
* [variables\_let\_const.md](/docs/javascript/variables-let-const)
* [template\_basics.md](/docs/javascript/template-basics)
* [console.md](/docs/javascript/console)


---

# History API (/docs/javascript/history-api)



# History API [#history-api]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The History API lets SPAs update the URL and session history without full reloads: `pushState`, `replaceState`, and the `popstate` event. Pair with the Navigation API / URL patterns for modern routing. Same-origin only for state URLs.

## 🔧 Core concepts [#-core-concepts]

* **`history.pushState(state, unused, url?)`**: add entry; no reload.
* **`history.replaceState(...)`**: replace current entry.
* **`history.state`**: current state object (structured-cloneable).
* **`history.back()` / `forward()` / `go(n)`**: traverse.
* **`popstate`**: fires on back/forward (not on `pushState` itself).
* **`hashchange`**: hash-only changes (older routing style).
* **Title arg**: ignored in modern browsers — update `document.title` yourself.

```js
history.pushState({ page: 2 }, "", "/page/2");
window.addEventListener("popstate", (e) => {
  render(e.state);
});
```

## 💡 Examples [#-examples]

```js
// Navigate in SPA
function navigate(path, state = {}) {
  history.pushState(state, "", path);
  renderRoute(path, state);
}

function replace(path, state = {}) {
  history.replaceState(state, "", path);
  renderRoute(path, state);
}

window.addEventListener("popstate", (e) => {
  renderRoute(location.pathname, e.state);
});

// Initial hydrate
renderRoute(location.pathname, history.state);

// Query updates without stacking junk
const url = new URL(location.href);
url.searchParams.set("q", query);
history.replaceState(history.state, "", url);

// Scroll restoration
if ("scrollRestoration" in history) {
  history.scrollRestoration = "manual";
}

// Guard external links vs internal
document.addEventListener("click", (e) => {
  const a = e.target.closest("a[href]");
  if (!a || a.origin !== location.origin || a.target === "_blank") return;
  if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
  e.preventDefault();
  navigate(a.pathname + a.search + a.hash);
});
```

```js
// State must be cloneable
history.pushState({ id: 1, when: new Date() }, "", "/item/1");
// history.pushState({ fn: () => {} }, "", "/x"); // DataCloneError
```

## ⚠️ Pitfalls [#️-pitfalls]

* `pushState` does not fire `popstate` — you must render yourself after push.
* State is structured-cloned — no functions, DOM nodes, or symbols.
* Relative URLs resolve against current URL — easy to create wrong paths.
* Back button through many `pushState` entries can feel sticky — use `replaceState` for filters.
* Cross-origin URLs throw — stay same-origin.

## 🔗 Related [#-related]

* [url.md](/docs/javascript/url) — URL / URLSearchParams
* [structured\_clone.md](/docs/javascript/structured-clone) — state cloning
* [DOM/navigation.md](/docs/javascript/dom/navigation) — location / navigation
* [DOM/events.md](/docs/javascript/dom/events) — popstate
* [encode.md](/docs/javascript/encode) — encoding query parts


---

# HTTP (Node) (/docs/javascript/http-node)



# HTTP (Node) [#http-node]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Node’s `node:http` / `node:https` build servers and clients. For most apps prefer frameworks (Express, Fastify) or `fetch` (Node 18+). This sheet covers the core APIs.

## 🔧 Core concepts [#-core-concepts]

| API                          | Role                             |
| ---------------------------- | -------------------------------- |
| `http.createServer(handler)` | HTTP server                      |
| `req` / `res`                | IncomingMessage / ServerResponse |
| `http.request` / `get`       | Outgoing client                  |
| `https`                      | TLS variants                     |
| `fetch(url)`                 | Modern client (undici)           |

## 💡 Examples [#-examples]

**Tiny server:**

```js
import http from 'node:http';

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({ ok: true, url: req.url }));
});

server.listen(9000, () => console.log('http://127.0.0.1:9000'));
```

**fetch client (Node 18+):**

```js
const res = await fetch('https://httpbin.org/get');
const data = await res.json();
console.log(data.url);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Always handle `error` on sockets; unhandled errors crash the process.
* Remember to `res.end()` or the request hangs.
* Prefer `fetch` / undici over hand-rolled `http.request` for clients.
* Binding `0.0.0.0` exposes the service on all interfaces.

## 🔗 Related [#-related]

* [fetch](/docs/javascript/fetch)
* [stream](/docs/javascript/stream)
* [process](/docs/javascript/process)
* [url\_node](/docs/javascript/url-node)
* [async](/docs/javascript/async)


---

# Import / Export (/docs/javascript/import-export)



# Import / Export [#import--export]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

ES modules (`import` / `export`) are the standard module system. Static imports are hoisted and analyzed at load time; dynamic `import()` returns a Promise. Use `.js` extensions in native ESM paths as required by the runtime.

## 🔧 Core concepts [#-core-concepts]

* **Named exports**: `export const x = 1`, `export function f() \{\}`, `export \{ a, b as c \}`.
* **Default export**: one per module — `export default expr`.
* **Import named**: `import \{ a, b as c \} from "./mod.js"`.
* **Import default**: `import Name from "./mod.js"`.
* **Namespace**: `import * as mod from "./mod.js"`.
* **Side-effect**: `import "./polyfill.js"`.
* **Dynamic**: `const mod = await import("./mod.js")`.
* **Re-export**: `export \{ x \} from "./x.js"`, `export * from "./x.js"`.

```js
// math.js
export const PI = Math.PI;
export function area(r) {
  return PI * r * r;
}
export default function sum(...ns) {
  return ns.reduce((a, b) => a + b, 0);
}
```

## 💡 Examples [#-examples]

```js
// consumer.js
import sum, { PI, area } from "./math.js";
import * as math from "./math.js";

console.log(area(2), sum(1, 2), math.PI);

// Rename
import { area as circleArea } from "./math.js";

// Dynamic / conditional
async function loadLocale(lang) {
  const mod = await import(`./locales/${lang}.js`);
  return mod.default;
}

// Import attributes (JSON modules — where supported)
import data from "./config.json" with { type: "json" };

// Re-export barrel
// index.js
export { area, PI } from "./math.js";
export { default as sum } from "./math.js";

// Top-level await in modules
const config = await fetch("/config.json").then((r) => r.json());
export { config };
```

```js
// Live bindings — exports are live
// counter.js
export let count = 0;
export function inc() {
  count += 1;
}

// main.js
import { count, inc } from "./counter.js";
inc();
console.log(count); // 1
```

## ⚠️ Pitfalls [#️-pitfalls]

* Mixing CommonJS `require` and ESM needs interop — prefer one system per package.
* Default + named: `import foo, \{ bar \}` — default is not in `\{ bar \}` unless also exported named.
* Circular imports can yield temporal dead zone / partial bindings — redesign cycles.
* Bundlers may tree-shake only static `import`; dynamic paths limit analysis.
* In browsers, modules need `type="module"` and usually CORS for file URLs.

## 🔗 Related [#-related]

* [objects.md](/docs/javascript/objects) — module namespaces as objects
* [async.md](/docs/javascript/async) — top-level await
* [promise.md](/docs/javascript/promise) — dynamic import()
* [json.md](/docs/javascript/json) — JSON module data
* [api.md](/docs/javascript/api) — runtime module loaders


---

# Intl (/docs/javascript/intl)



# Intl [#intl]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `Intl` namespace provides locale-aware formatting and comparison: dates, numbers, lists, relative time, plurals, and collation. Prefer `Intl` over hand-rolled locale strings for i18n correctness and accessibility.

## 🔧 Core concepts [#-core-concepts]

| Constructor               | Use                    |
| ------------------------- | ---------------------- |
| `Intl.DateTimeFormat`     | dates/times            |
| `Intl.NumberFormat`       | numbers/currency/units |
| `Intl.RelativeTimeFormat` | “3 days ago”           |
| `Intl.ListFormat`         | “A, B, and C”          |
| `Intl.PluralRules`        | plural categories      |
| `Intl.Collator`           | sort / compare strings |
| `Intl.DisplayNames`       | language/region names  |
| `Intl.Segmenter`          | grapheme/word segments |

* **Locales**: BCP 47 tags — `"en"`, `"en-US"`, `"de-DE"`, `navigator.language`.
* **Options**: style, currency, timeZone, numberingSystem, etc.
* **`supportedLocalesOf`**: feature detection for locale lists.

```js
new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
}).format(1234.5); // "$1,234.50"
```

## 💡 Examples [#-examples]

```js
const locale = navigator.language || "en";

// Dates
new Intl.DateTimeFormat(locale, {
  dateStyle: "medium",
  timeStyle: "short",
}).format(new Date());

// Time zone
new Intl.DateTimeFormat("en-GB", {
  timeZone: "UTC",
  timeStyle: "long",
}).format(new Date());

// Relative
new Intl.RelativeTimeFormat(locale, { numeric: "auto" }).format(-1, "day");
// "yesterday" (en)

// Lists
new Intl.ListFormat(locale, { style: "long", type: "conjunction" }).format([
  "red",
  "green",
  "blue",
]);

// Sort
const collator = new Intl.Collator(locale, { sensitivity: "base" });
["ä", "a", "z"].sort(collator.compare);

// Plurals
const pr = new Intl.PluralRules("ru");
pr.select(3); // "few" etc.

// Display names
new Intl.DisplayNames("en", { type: "language" }).of("fr"); // "French"
```

```js
// Compact notation
new Intl.NumberFormat("en", {
  notation: "compact",
  compactDisplay: "short",
}).format(1_200_000); // "1.2M"
```

## ⚠️ Pitfalls [#️-pitfalls]

* Locale data availability varies by engine — test critical locales.
* Don’t concatenate translated fragments — format whole messages (use ICU MessageFormat libs for complex cases).
* `Date#toLocaleString` is convenient but less reusable than a shared `DateTimeFormat` instance.
* Currency requires ISO codes (`USD`), not symbols alone.
* Sorting without `Collator` breaks non-English languages.

## 🔗 Related [#-related]

* [date.md](/docs/javascript/date) — Date object
* [number.md](/docs/javascript/number) — numeric values
* [strings.md](/docs/javascript/strings) — string compare
* [template\_literals.md](/docs/javascript/template-literals) — building messages
* [performance.md](/docs/javascript/performance) — reuse formatters


---

# Iteration (/docs/javascript/iteration)



# Iteration [#iteration]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

JavaScript offers several iteration styles: index `for`, `for...of`, `for...in`, `while`, array methods, and iterators/generators. Choose based on whether you need indices, early exit, async, or transformation pipelines.

## 🔧 Core concepts [#-core-concepts]

* **Indexed `for`**: full control of index and step.
* **`for...of`**: values from iterables.
* **`for...in`**: enumerable keys (objects) — rarely for arrays.
* **Array methods**: `forEach`, `map`, `filter`, `reduce` — functional pipelines; `forEach` cannot `break`.
* **`while` / `do...while`**: condition-driven loops.
* **Async**: `for await...of`, or `Promise.all` over mapped async work.

```js
for (let i = 0; i < arr.length; i++) {
  /* index + value: arr[i] */
}
```

## 💡 Examples [#-examples]

```js
const arr = ["a", "b", "c"];

// Indices + values
for (const [i, v] of arr.entries()) {
  console.log(i, v);
}

// Object keys / values / entries
const obj = { x: 1, y: 2 };
for (const key of Object.keys(obj)) console.log(key);
for (const val of Object.values(obj)) console.log(val);
for (const [k, v] of Object.entries(obj)) console.log(k, v);

// Pipeline
const sum = arr
  .map((s) => s.toUpperCase())
  .filter((s) => s !== "B")
  .reduce((acc, s) => acc + s.length, 0);

// forEach (no break)
arr.forEach((v, i) => console.log(i, v));

// Early exit → for...of
for (const v of arr) {
  if (v === "b") break;
}

// Nested with labeled break
outer: for (const row of matrix) {
  for (const cell of row) {
    if (cell < 0) break outer;
  }
}
```

```js
// Async sequential
for (const url of urls) {
  await fetch(url);
}

// Async parallel
await Promise.all(urls.map((u) => fetch(u)));

// Generator-driven
function* walk(node) {
  yield node;
  for (const child of node.children ?? []) yield* walk(child);
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `forEach` ignores `async` callbacks’ promises and cannot break.
* `for...in` on arrays includes enumerable extras and yields string keys.
* Mutating length while iterating with index `for` needs care.
* Prefer `Object.keys` / `entries` over `for...in` for own properties.

## 🔗 Related [#-related]

* [for\_of.md](/docs/javascript/for-of) — for...of details
* [while.md](/docs/javascript/while) — while loops
* [iterator.md](/docs/javascript/iterator) — iterators & generators
* [arrays.md](/docs/javascript/arrays) — map/filter/reduce
* [objects.md](/docs/javascript/objects) — key enumeration
* [async.md](/docs/javascript/async) — async iteration
* [map.md](/docs/javascript/map) — Map iteration order


---

# Iterators & Generators (/docs/javascript/iterator)



# Iterators & Generators [#iterators--generators]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

The **iterable protocol** (`obj[Symbol.iterator]`) supplies an iterator with `next()` → `\{ value, done \}`. **Generators** (`function*`) produce iterators lazily and support `yield` / `yield*`. Async generators use `async function*` and `for await...of`.

## 🔧 Core concepts [#-core-concepts]

* **Iterable**: has `[Symbol.iterator]()` returning an iterator.
* **Iterator**: `\{ next() \}`; optional `return()` / `throw()`.
* **Generator**: `function*` pauses at `yield`; calling it returns a generator object.
* **`yield*`**: delegate to another iterable/generator.
* **Async**: `async function*`, `yield` awaited values, consume with `for await`.

```js
const iterable = {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
  },
};
[...iterable]; // [1, 2]
```

## 💡 Examples [#-examples]

```js
function* range(start, end, step = 1) {
  for (let i = start; i < end; i += step) yield i;
}
console.log([...range(0, 5)]); // [0,1,2,3,4]

function* idGen() {
  let id = 1;
  while (true) yield id++;
}
const ids = idGen();
ids.next().value; // 1

// yield*
function* flatten(arr) {
  for (const x of arr) {
    if (Array.isArray(x)) yield* flatten(x);
    else yield x;
  }
}
[...flatten([1, [2, [3], 4]])]; // [1,2,3,4]

// Manual iterator
const it = range(0, 2);
console.log(it.next()); // { value: 0, done: false }
console.log(it.next());
console.log(it.next()); // { value: undefined, done: true }

// Async generator
async function* poll(url, signal) {
  while (!signal.aborted) {
    const data = await fetch(url, { signal }).then((r) => r.json());
    yield data;
    await new Promise((r) => setTimeout(r, 1000));
  }
}
```

```js
// Infinite take helper
function take(n, iterable) {
  return {
    *[Symbol.iterator]() {
      let i = 0;
      for (const v of iterable) {
        if (i++ >= n) return;
        yield v;
      }
    },
  };
}
[...take(3, idGen())]; // [1,2,3]
```

## ⚠️ Pitfalls [#️-pitfalls]

* Generators are lazy — side effects run only as you pull values.
* After `done: true`, further `next()` stay done (unless still open with return values).
* `break` in `for...of` calls iterator `return()` — use `try/finally` in generators for cleanup.
* Do not mix sync `for...of` with async generators — use `for await...of`.
* Spreading infinite generators never finishes.

## 🔗 Related [#-related]

* [for\_of.md](/docs/javascript/for-of) — consuming iterables
* [iteration.md](/docs/javascript/iteration) — loop overview
* [arrays.md](/docs/javascript/arrays) — Array.from / spread
* [async.md](/docs/javascript/async) — async iteration
* [map.md](/docs/javascript/map) — built-in iterables
* [set.md](/docs/javascript/set) — built-in iterables


---

# JSON (/docs/javascript/json)



# JSON [#json]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

JSON is a text data format. `JSON.parse` and `JSON.stringify` convert between strings and plain data (objects, arrays, numbers, strings, booleans, `null`). Functions, `undefined`, Symbols, and many class instances need custom handling.

## 🔧 Core concepts [#-core-concepts]

* **`JSON.parse(text, reviver?)`**: string → value; throws `SyntaxError` on bad input.
* **`JSON.stringify(value, replacer?, space?)`**: value → string; omits `undefined` in objects.
* **Reviver / replacer**: transform keys during parse/stringify.
* **`toJSON()`**: objects can customize serialization.
* **Safe parse**: wrap in try/catch; validate shape after parse.

```js
const obj = JSON.parse('{"a":1}');
const text = JSON.stringify(obj, null, 2);
```

## 💡 Examples [#-examples]

```js
// Pretty print
JSON.stringify({ user: "Ada", ok: true }, null, 2);

// Replacer allowlist
JSON.stringify(user, ["id", "name"]);

// Reviver for dates
const parsed = JSON.parse(payload, (key, value) => {
  if (key.endsWith("At") && typeof value === "string") {
    const d = new Date(value);
    if (!Number.isNaN(d.getTime())) return d;
  }
  return value;
});

// toJSON
const money = {
  amount: 10,
  currency: "USD",
  toJSON() {
    return `${this.amount} ${this.currency}`;
  },
};
JSON.stringify({ price: money }); // {"price":"10 USD"}

// Map ↔ JSON
function mapToJson(map) {
  return JSON.stringify([...map.entries()]);
}
function jsonToMap(text) {
  return new Map(JSON.parse(text));
}

// Deep clone via JSON (limitations!)
const clone = JSON.parse(JSON.stringify(data));
```

```js
function safeParse(text, fallback = null) {
  try {
    return JSON.parse(text);
  } catch {
    return fallback;
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `JSON.stringify` drops `undefined`, functions, and Symbols in objects; turns them to `null` in arrays for `undefined`/functions.
* `NaN` / `Infinity` become `null`.
* `Date` becomes ISO string; `Map`/`Set` become `\{\}` unless converted.
* Circular structures throw `TypeError`.
* JSON clone loses prototypes, methods, and `undefined` keys.

## 🔗 Related [#-related]

* [objects.md](/docs/javascript/objects) — plain objects
* [arrays.md](/docs/javascript/arrays) — JSON arrays
* [fetch.md](/docs/javascript/fetch) — JSON HTTP bodies
* [date.md](/docs/javascript/date) — Date ↔ ISO
* [map.md](/docs/javascript/map) — serializing Maps
* [error.md](/docs/javascript/error) — SyntaxError on parse
* [strings.md](/docs/javascript/strings) — text handling


---

# Map (/docs/javascript/map)



# Map [#map]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`Map` is a keyed collection that preserves insertion order and accepts any value as a key (including objects). Prefer `Map` over plain objects when keys are unknown, non-strings, or you need reliable size / iteration.

## 🔧 Core concepts [#-core-concepts]

* **Create**: `new Map()`, `new Map([[k, v], ...])`.
* **Mutate**: `set`, `get`, `has`, `delete`, `clear`.
* **Size**: `map.size` (not a method).
* **Iterate**: `keys()`, `values()`, `entries()`, `forEach`, `for...of`.
* **Key equality**: SameValueZero (`NaN` equals `NaN`; `+0` / `-0` equal).

```js
const m = new Map();
m.set("a", 1).set("b", 2);
m.get("a"); // 1
m.size; // 2
```

## 💡 Examples [#-examples]

```js
// Object keys by reference
const user = { id: 1 };
const scores = new Map();
scores.set(user, 100);
scores.get(user); // 100

// Build from object
const fromObj = new Map(Object.entries({ x: 1, y: 2 }));

// To object (string keys only)
const obj = Object.fromEntries(fromObj);

// Frequency map
function frequencies(list) {
  const freq = new Map();
  for (const item of list) {
    freq.set(item, (freq.get(item) ?? 0) + 1);
  }
  return freq;
}

// Default get
function getOr(map, key, factory) {
  if (!map.has(key)) map.set(key, factory());
  return map.get(key);
}

// Iterate
for (const [k, v] of scores) console.log(k, v);

// Group into Map
function groupBy(list, keyFn) {
  const map = new Map();
  for (const item of list) {
    const key = keyFn(item);
    getOr(map, key, () => []).push(item);
  }
  return map;
}
```

```js
// WeakMap — keys must be objects; not iterable; GC-friendly
const privateState = new WeakMap();
function attach(el) {
  privateState.set(el, { clicks: 0 });
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Object keys are by **reference**, not deep equality.
* `JSON.stringify(map)` → `"\{\}"` — convert with `Object.fromEntries` or entries array.
* `map["a"] = 1` does not use Map storage — always use `.set` / `.get`.
* `WeakMap` is not iterable and cannot use primitive keys.
* Converting to object fails for non-string/symbol keys.

## 🔗 Related [#-related]

* [set.md](/docs/javascript/set) — Set collections
* [objects.md](/docs/javascript/objects) — plain object maps
* [iteration.md](/docs/javascript/iteration) — iterating Maps
* [for\_of.md](/docs/javascript/for-of) — for...of entries
* [json.md](/docs/javascript/json) — serialization
* [arrays.md](/docs/javascript/arrays) — Object.groupBy


---

# Math (/docs/javascript/math)



# Math [#math]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`Math` is a built-in object of numeric constants and functions. It works on IEEE-754 numbers (not `BigInt`). Prefer `Math` helpers over hand-rolled formulas for clamping, rounding, and trig.

## 🔧 Core concepts [#-core-concepts]

* **Constants**: `Math.PI`, `Math.E`, `Math.LN2`, `Math.SQRT2`, …
* **Rounding**: `floor`, `ceil`, `round`, `trunc`, `fround`.
* **Min/max**: `Math.min(...)`, `Math.max(...)` — watch empty call → `Infinity` / `-Infinity`.
* **Random**: `Math.random()` ∈ `[0, 1)`.
* **Powers**: `sqrt`, `cbrt`, `pow`, `**` operator, `hypot`, `abs`, `sign`.
* **Trig**: `sin`, `cos`, `tan`, `atan2` (radians).

```js
Math.clamp?.(0, 5, 10); // if available; else DIY
const clamp = (n, min, max) => Math.min(max, Math.max(min, n));
```

## 💡 Examples [#-examples]

```js
const clamp = (n, min, max) => Math.min(max, Math.max(min, n));
clamp(120, 0, 100); // 100

Math.trunc(3.9); // 3
Math.floor(-3.1); // -4
Math.trunc(-3.1); // -3

// Inclusive integer random
function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

// Sum with hypot for distance
const dist = Math.hypot(dx, dy);

// Percentage
const pct = Math.round((done / total) * 100);

// Avoid float noise for currency — use integers (cents) or Decimal libs
const cents = Math.round(19.99 * 100); // 1999

// Spread min/max on arrays
const nums = [3, 1, 4];
Math.max(...nums); // 4
// Large arrays: use loop or reduce to avoid stack limits
nums.reduce((a, b) => Math.max(a, b), -Infinity);
```

```js
// Angle helpers
const toRad = (deg) => (deg * Math.PI) / 180;
const toDeg = (rad) => (rad * 180) / Math.PI;
Math.sin(toRad(90)); // ~1

// imul / clz32 for bit ops
Math.imul(0xffffffff, 2);

// Sign & absolute
Math.sign(-0); // -0
Math.abs(-4.2); // 4.2
Math.log2(8); // 3
```

## ⚠️ Pitfalls [#️-pitfalls]

* `Math.max()` with no args is `-Infinity`; `Math.min()` is `Infinity`.
* `Math.round` uses “round half away from zero” toward +∞ for `.5` on positives.
* Floating point: `0.1 + 0.2 !== 0.3` — compare with epsilon.
* `Math.random` is not cryptographically secure — use `crypto.getRandomValues`.
* Spreading huge arrays into `Math.max` can throw RangeError.

## 🔗 Related [#-related]

* [number.md](/docs/javascript/number) — Number methods & parsing
* [date.md](/docs/javascript/date) — time arithmetic
* [api.md](/docs/javascript/api) — crypto random
* [arrays.md](/docs/javascript/arrays) — reduce aggregates
* [boolean.md](/docs/javascript/boolean) — comparisons


---

# Modules (CommonJS) (/docs/javascript/modules-commonjs)



# Modules (CommonJS) [#modules-commonjs]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

CommonJS (CJS) is Node’s classic module system: `require`, `module.exports`, and synchronous loading. ES modules (`import`/`export`) are the web standard and Node’s modern default — know CJS for legacy packages, interop, and tooling. Prefer ESM for new browser and Node code.

## 🔧 Core concepts [#-core-concepts]

* **Export**: `module.exports = value` or `exports.foo = ...` (alias of `module.exports` initially).
* **Import**: `const x = require("./file")` — cached after first load.
* **Resolution**: core modules, `node_modules`, relative paths; optional extensions.
* **`__filename` / `__dirname`**: file path helpers (not in ESM — use `import.meta.url`).
* **Circular deps**: partially filled `exports` during cycle.
* **Interop**: ESM can sometimes `import` CJS; CJS loads ESM via dynamic `import()`.

```js
// math.cjs
function add(a, b) {
  return a + b;
}
module.exports = { add };
```

## 💡 Examples [#-examples]

```js
// Export patterns
module.exports = function main() {};
module.exports = { read, write };
exports.version = "1.0.0"; // OK if not reassigned module.exports

// BAD: breaks exports alias
exports = { a: 1 }; // does not change module.exports

// Import
const { add } = require("./math");
const path = require("node:path");

// Conditional / dynamic path
const lang = require(`./locales/${name}.js`); // still sync; path must be resolvable

// Cache bust (rare)
delete require.cache[require.resolve("./config")];

// ESM consuming CJS (typical bundler/Node)
import pkg from "./legacy.cjs";
import * as ns from "./legacy.cjs";

// CJS consuming ESM
async function load() {
  const esm = await import("./modern.mjs");
  return esm.default;
}

// __dirname in ESM
import { fileURLToPath } from "node:url";
import { dirname } from "node:path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Reassigning `exports = ...` does not export — assign `module.exports`.
* `require` is sync and blocks — avoid for huge optional deps at startup when dynamic `import` fits.
* Dual packages (CJS+ESM) can cause “duplicate instance” bugs — follow package `exports` map.
* Browser has no native `require` — use ESM or a bundler.
* Live bindings differ: CJS copies values on require; ESM exports are live.

## 🔗 Related [#-related]

* [import\_export.md](/docs/javascript/import-export) — ES modules
* [oop.md](/docs/javascript/oop) — organizing code
* [json.md](/docs/javascript/json) — require JSON in Node
* [error.md](/docs/javascript/error) — MODULE\_NOT\_FOUND


---

# new Operator (/docs/javascript/new)



# new Operator [#new-operator]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`new` constructs an instance from a constructor function or class. It creates an object, sets its prototype, binds `this`, and returns the object (unless the constructor returns another object).

## 🔧 Core concepts [#-core-concepts]

* **Steps**: create `\{\}` → set `[[Prototype]]` → call constructor with `this` → return object (or explicit object return).
* **Classes**: `new Person()` required; calling without `new` throws.
* **`new.target`**: meta-property detecting construct calls.
* **`new.target` / subclassing**: works with `extends` and `super`.
* **Built-ins**: `new Map()`, `new Date()`, `new Error()` — some built-ins differ if called as functions.

```js
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}
const p = new Point(1, 2);
```

## 💡 Examples [#-examples]

```js
// Classic constructor
function User(name) {
  if (new.target === undefined) {
    return new User(name); // allow factory-style call
  }
  this.name = name;
}
User.prototype.hello = function () {
  return `Hi, ${this.name}`;
};

const u = new User("Ada");
u instanceof User; // true
Object.getPrototypeOf(u) === User.prototype; // true

// Class fields & private
class Counter {
  #n = 0;
  get value() {
    return this.#n;
  }
  inc() {
    this.#n += 1;
  }
}
const c = new Counter();

// Return override
function Weird() {
  this.a = 1;
  return { b: 2 }; // instance discarded
}
new Weird(); // { b: 2 }

// Reflect.construct
const d = Reflect.construct(Date, [2026, 0, 1]);
```

```js
// Array exotic
const a = new Array(3); // length 3 sparse
const b = Array.of(3); // [3]
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting `new` on old constructors sets properties on the global/`undefined` (strict) — prefer `class`.
* Returning a primitive from a constructor is ignored; returning an object replaces `this`.
* `arrow functions` cannot be constructors — no `new`.
* `Symbol` / `BigInt` are not constructible with `new`.
* `instanceof` can be spoofed; use brands or `new.target` checks for security-sensitive code.

## 🔗 Related [#-related]

* [oop.md](/docs/javascript/oop) — classes & inheritance
* [objects.md](/docs/javascript/objects) — prototypes
* [properties.md](/docs/javascript/properties) — defining instance props
* [error.md](/docs/javascript/error) — `new Error`
* [map.md](/docs/javascript/map) — `new Map`
* [date.md](/docs/javascript/date) — `new Date`


---

# OS module (/docs/javascript/node-os)



# OS module [#os-module]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Node.js `node:os` reports host operating system details: home/temp directories, platform, CPU info, memory, and network interfaces. Useful for tools, diagnostics, and default paths — not a substitute for feature detection in app logic.

```js
import os from "node:os";
```

## 🔧 Core concepts [#-core-concepts]

* **`homedir()`**: current user’s home directory.
* **`tmpdir()`**: default directory for temporary files.
* **`platform()`**: `'darwin' | 'linux' | 'win32' | …` (Node’s naming).
* **`type()` / `release()` / `arch()`**: OS name, version string, CPU arch (`x64`, `arm64`).
* **`cpus()`**: array of CPU core descriptors (`model`, `speed`, `times`).
* **`totalmem()` / `freemem()`**: RAM in bytes.
* **`hostname()` / `networkInterfaces()`**: machine name and NICs.
* **`EOL`**: end-of-line sequence (`\n` or `\r\n`).

## 💡 Examples [#-examples]

```js
import os from "node:os";
import path from "node:path";

const configDir = path.join(os.homedir(), ".myapp");
const scratch = path.join(os.tmpdir(), "myapp-cache");

console.log(os.platform(), os.arch(), os.release());
console.log("cores:", os.cpus().length);
console.log("free MB:", Math.round(os.freemem() / 1024 / 1024));

const cpus = os.cpus();
console.log(cpus[0]?.model);

// Cross-platform line join
const lines = ["a", "b", "c"].join(os.EOL);

const ifaces = os.networkInterfaces();
for (const [name, addrs] of Object.entries(ifaces)) {
  for (const a of addrs ?? []) {
    if (a.family === "IPv4" && !a.internal) {
      console.log(name, a.address);
    }
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `platform()` returns `'win32'` even on 64-bit Windows.
* `cpus().length` is logical cores (HT), not necessarily physical packages.
* `tmpdir()` / `homedir()` can throw or be unexpected in restricted containers.
* `networkInterfaces()` shape varies; filter `internal` and family carefully (`IPv4` vs `4` in older Node).
* Do not hardcode separators — combine with `path` and `os.EOL`.

## 🔗 Related [#-related]

* [Path](/docs/javascript/path) — join home/tmp with filenames
* [process](/docs/javascript/process) — env, cwd, platform via process
* [fs](/docs/javascript/fs) — create dirs under homedir/tmpdir
* [child\_process](/docs/javascript/child-process) — OS-specific binaries


---

# null and undefined (/docs/javascript/null-undefined)



# null and undefined [#null-and-undefined]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

JavaScript has two empty-ish values: `undefined` (missing / not set) and `null` (intentional empty). Beginners should treat them as related but not identical, and prefer strict equality.

## 🔧 Core concepts [#-core-concepts]

| Value       | Usual meaning                               | How you get it                |
| ----------- | ------------------------------------------- | ----------------------------- |
| `undefined` | Not assigned / missing property / no return | Default state                 |
| `null`      | Deliberate “no object”                      | You (or an API) set it        |
| `==`        | Loose equality                              | `null == undefined` is `true` |
| `===`       | Strict equality                             | Prefer this                   |

Optional chaining (`?.`) and nullish coalescing (`??`) help handle both safely.

## 💡 Examples [#-examples]

**undefined by default:**

```js
let x;
console.log(x);            // undefined
console.log(typeof x);     // undefined

function f() {}
console.log(f());          // undefined
```

**null as intentional empty:**

```js
let user = null;
if (user === null) {
  console.log("logged out");
}
user = { name: "Ada" };
console.log(user.name);
```

**Loose vs strict:**

```js
console.log(null == undefined);  // true
console.log(null === undefined); // false
console.log(null === null);      // true
```

**Nullish coalescing and optional chaining:**

```js
const input = null;
const label = input ?? "default";
console.log(label); // default

const settings = undefined;
console.log(settings?.theme ?? "light"); // light
```

## ⚠️ Pitfalls [#️-pitfalls]

* Prefer `===` so you do not conflate `null` and `undefined` accidentally.
* `??` only falls through for `null`/`undefined`; `||` also treats `0`, `""`, `false` as missing.
* `typeof null` is `"object"` — do not use typeof to detect null.
* Reading missing nested props without `?.` throws: `obj.a.b`.

## 🔗 Related [#-related]

* [typeof\_basics.md](/docs/javascript/typeof-basics)
* [variables\_let\_const.md](/docs/javascript/variables-let-const)
* [nullish\_coalescing.md](/docs/javascript/nullish-coalescing)
* [equality.md](/docs/javascript/equality)


---

# Nullish Coalescing (/docs/javascript/nullish-coalescing)



# Nullish Coalescing [#nullish-coalescing]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The nullish coalescing operator (`??`) returns the right-hand side only when the left is `null` or `undefined`. Unlike `||`, it preserves intentional falsy values like `0`, `""`, and `false`. Pair with `?.` for safe defaults.

## 🔧 Core concepts [#-core-concepts]

* **`a ?? b`**: if `a` is nullish → `b`, else `a`.
* **`??=`**: assign only if current value is nullish.
* **Precedence**: cannot mix `??` with `&&` / `||` without parentheses.
* **vs `||`**: `||` treats all falsy as missing; `??` only nullish.
* **vs ternary**: `a != null ? a : b` is roughly equivalent (note `!=` coerces).

```js
const port = config.port ?? 3000;
const name = input.name ?? "Anonymous";
```

## 💡 Examples [#-examples]

```js
0 || 42; // 42  (often wrong for counts)
0 ?? 42; // 0

"" || "default"; // "default"
"" ?? "default"; // ""

null ?? "x"; // "x"
undefined ?? "x"; // "x"

// Nested options
const timeout = opts?.timeout ?? 5000;

// Assignment
let theme;
theme ??= "light";
theme ??= "dark"; // stays "light"

// Function defaults (params already handle undefined)
function connect(host, port = 443) {
  // port default only for undefined
}
connect("a", undefined); // 443
connect("a", null); // null — use ?? if null should default
function connect2(host, port) {
  port = port ?? 443;
}

// Prefer ?? for map lookups
const label = dict.get(key) ?? "missing";
```

```js
// Parentheses required
// const x = a || b ?? c; // SyntaxError
const x = (a || b) ?? c;
const y = a || (b ?? c);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Mixing `??` with `||`/`&&` without parens is a syntax error.
* `document.all ?? x` is a weird legacy exception in some engines — ignore in modern code.
* Defaults in destructuring use `=` which also only triggers on `undefined`, not `null` — combine carefully.
* `??` does not deep-merge objects — only picks one side.

## 🔗 Related [#-related]

* [optional\_chaining.md](/docs/javascript/optional-chaining) — `?.` + `??`
* [equality.md](/docs/javascript/equality) — null vs undefined
* [destructuring.md](/docs/javascript/destructuring) — default values
* [ternary.md](/docs/javascript/ternary) — explicit conditionals
* [boolean.md](/docs/javascript/boolean) — truthiness


---

# Number (/docs/javascript/number)



# Number [#number]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`number` is IEEE-754 double precision. Integers are safe up to `Number.MAX_SAFE_INTEGER` (`2^53 - 1`). Use `BigInt` for larger integers. Prefer `Number` static methods over global `parseInt` / `isNaN` when possible.

## 🔧 Core concepts [#-core-concepts]

* **Literals**: `42`, `3.14`, `0xff`, `0b1010`, `1e3`, separators `1_000_000`.
* **Constants**: `MAX_VALUE`, `MIN_VALUE`, `EPSILON`, `NaN`, `POSITIVE_INFINITY`.
* **Check**: `Number.isFinite`, `Number.isInteger`, `Number.isSafeInteger`, `Number.isNaN`.
* **Parse**: `Number(text)`, `Number.parseInt(text, radix)`, `Number.parseFloat`.
* **Format**: `toFixed`, `toPrecision`, `toString(radix)`, `toLocaleString`, `Intl.NumberFormat`.

```js
Number.isNaN(Number("x")); // true
Number.parseInt("10px", 10); // 10
```

## 💡 Examples [#-examples]

```js
const n = 1_000_000.5;
n.toFixed(2); // "1000000.50"

// Safe integer check
function addSafe(a, b) {
  const s = a + b;
  if (!Number.isSafeInteger(s)) throw new RangeError("unsafe");
  return s;
}

// Epsilon compare
function nearlyEqual(a, b, eps = Number.EPSILON) {
  return Math.abs(a - b) < eps;
}
nearlyEqual(0.1 + 0.2, 0.3);

// Parse with radix
Number.parseInt("08", 10); // 8
Number.parseInt("ff", 16); // 255

// Locale currency
new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
}).format(19.9);

// BigInt interop
const big = 10n;
Number(big); // 10 — may lose precision for huge BigInts
BigInt(42); // 42n

// Unary plus
+"42"; // 42
+""; // 0
+null; // 0
+undefined; // NaN
```

```js
// Clamp percent
const pct = Math.min(100, Math.max(0, value));
```

## ⚠️ Pitfalls [#️-pitfalls]

* Global `isNaN` coerces: `isNaN("foo") === true`; use `Number.isNaN`.
* `parseInt` without radix can surprise on leading zeros in old engines — always pass radix.
* `==` coerces strings/numbers; use `===` after explicit parse.
* Floating point drift — don’t use binary floats for money.
* `typeof NaN === "number"`.

## 🔗 Related [#-related]

* [math.md](/docs/javascript/math) — Math helpers
* [boolean.md](/docs/javascript/boolean) — falsy `0` / `NaN`
* [strings.md](/docs/javascript/strings) — parsing from text
* [json.md](/docs/javascript/json) — number serialization
* [date.md](/docs/javascript/date) — timestamps


---

# Objects (/docs/javascript/objects)



# Objects [#objects]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

Objects are key/value maps with a prototype chain. Prefer plain objects for records with known string keys; use `Map` for dynamic or non-string keys. Modern syntax covers shorthand, spread, optional chaining, and nullish assignment.

## 🔧 Core concepts [#-core-concepts]

**Create / copy / merge**

| API                              | Notes                                |
| -------------------------------- | ------------------------------------ |
| `\{\}`, `\{ ...a, ...b \}`       | Literal; shallow merge (later wins)  |
| `Object.create(proto, props?)`   | Set prototype; optional descriptors  |
| `Object.assign(target, ...srcs)` | Shallow copy own enumerable → target |
| `Object.fromEntries(iterable)`   | `[[k,v],…]` → object                 |
| `structuredClone(obj)`           | Deep clone (structured-cloneable)    |

**Keys / values / entries / own checks**

| API                               | Notes                                               |
| --------------------------------- | --------------------------------------------------- |
| `Object.keys(o)`                  | Own enumerable string keys                          |
| `Object.values(o)`                | Own enumerable string-key values                    |
| `Object.entries(o)`               | `[key, value]` pairs                                |
| `Object.hasOwn(o, key)`           | Own property (ES2022); prefer over `hasOwnProperty` |
| `Object.getOwnPropertyNames(o)`   | Own string keys incl. non-enumerable                |
| `Object.getOwnPropertySymbols(o)` | Own symbol keys                                     |
| `Reflect.ownKeys(o)`              | Names + symbols                                     |

**Prototype / integrity**

| API                                             | Notes                               |
| ----------------------------------------------- | ----------------------------------- |
| `Object.getPrototypeOf` / `setPrototypeOf`      | Read/set `[[Prototype]]`            |
| `Object.is(a, b)`                               | SameValue (`NaN`≡`NaN`, `+0`≠`-0`)  |
| `Object.freeze(o)`                              | No add/remove/reconfigure; shallow  |
| `Object.seal(o)`                                | No add/remove; existing writable ok |
| `Object.preventExtensions(o)`                   | No new props                        |
| `Object.isFrozen` / `isSealed` / `isExtensible` | Integrity queries                   |
| `Object.groupBy(items, fn)`                     | Group iterable → object of arrays   |

**Property descriptors**

| Field / API                             | Notes                                     |
| --------------------------------------- | ----------------------------------------- |
| `value`, `writable`                     | Data property                             |
| `get`, `set`                            | Accessor property (no `value`/`writable`) |
| `enumerable`                            | Shown in `for…in` / `keys` / spread       |
| `configurable`                          | Can delete / reconfigure                  |
| `Object.getOwnPropertyDescriptor(o, k)` | One descriptor                            |
| `Object.getOwnPropertyDescriptors(o)`   | All own descriptors                       |
| `Object.defineProperty(o, k, desc)`     | Define/reconfigure one                    |
| `Object.defineProperties(o, descs)`     | Define many                               |

Access: `obj.key`, `obj["key"]`, `obj?.key`. Nullish: `??`, `??=`.

```js
const user = { id: 1, name: "Ada" };
const { name, ...rest } = user;
```

## 💡 Examples [#-examples]

```js
// Shorthand & methods
const x = 1;
const o = {
  x,
  greet() {
    return "hi";
  },
  get label() {
    return String(this.x);
  },
};

// Merge (shallow)
const merged = { ...defaults, ...overrides };

// Optional chaining / nullish
const city = user?.address?.city ?? "unknown";
user.role ??= "guest";

// fromEntries / entries round-trip
const mapish = Object.fromEntries(
  Object.entries(user).map(([k, v]) => [k.toUpperCase(), v]),
);

// Own property checks
Object.hasOwn(user, "name"); // ES2022
Object.prototype.hasOwnProperty.call(user, "name"); // legacy-safe

// Freeze / seal
const cfg = Object.freeze({ mode: "prod" });

// structuredClone deep copy
const copy = structuredClone({ nested: { a: 1 }, when: new Date() });

// Prototype-free dict
const dict = Object.create(null);
dict.admin = true;
```

```js
// GroupBy (ES2024)
Object.groupBy(items, (i) => i.type);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Spread/assign are **shallow** — nested objects stay shared.
* `__proto__` key in JSON can pollute prototypes — use `Object.create(null)` or `Map`.
* `for...in` walks the prototype chain — prefer `Object.keys` / `hasOwn`.
* Comparing objects with `===` is by reference, not deep equality.
* `JSON.stringify` omits `undefined` values and functions.

## 🔗 Related [#-related]

* [properties.md](/docs/javascript/properties) — descriptors & getters
* [oop.md](/docs/javascript/oop) — classes / prototypes
* [map.md](/docs/javascript/map) — Map vs object
* [json.md](/docs/javascript/json) — serialization
* [iteration.md](/docs/javascript/iteration) — enumerating keys
* [new.md](/docs/javascript/new) — constructing instances


---

# OOP (Classes & Prototypes) (/docs/javascript/oop)



# OOP (Classes & Prototypes) [#oop-classes--prototypes]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

JavaScript OOP is prototype-based. `class` syntax is sugar over constructor functions and prototypes, adding inheritance via `extends`, `super`, public/private fields, and static members.

## 🔧 Core concepts [#-core-concepts]

* **Class**: `constructor`, instance methods, getters/setters, fields.
* **Private**: `#field`, `#method` — truly private per class.
* **Static**: `static` props/methods on the constructor.
* **Inheritance**: `extends`, `super()` before using `this` in subclass constructors.
* **Prototype**: `obj.__proto__` / `Object.getPrototypeOf`; methods live on `.prototype`.
* **`instanceof`**: walks the prototype chain.

```js
class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    return `${this.name} makes a noise`;
  }
}
```

## 💡 Examples [#-examples]

```js
class Dog extends Animal {
  #tricks = [];

  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }

  speak() {
    return `${super.speak()} — woof`;
  }

  addTrick(t) {
    this.#tricks.push(t);
  }

  get tricks() {
    return [...this.#tricks];
  }

  static fromJSON(json) {
    const data = JSON.parse(json);
    return new Dog(data.name, data.breed);
  }
}

const d = new Dog("Rex", "lab");
d instanceof Dog; // true
d instanceof Animal; // true

// Mix-in pattern
const Timestamped = (Base) =>
  class extends Base {
    createdAt = new Date();
  };
class Job extends Timestamped(Object) {}

// Prototype check
Object.getPrototypeOf(d) === Dog.prototype;
```

```js
// Composition over deep hierarchies
class Engine {
  start() {
    return "vroom";
  }
}
class Car {
  constructor() {
    this.engine = new Engine();
  }
  start() {
    return this.engine.start();
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Subclass constructors must call `super()` before accessing `this`.
* Arrow methods as class fields are not on the prototype (per-instance; can’t be easily mocked via proto).
* Private fields are not accessible in subclasses or outside the declaring class.
* `this` in callbacks needs binding or arrows — class methods are not auto-bound.
* Overusing inheritance creates brittle hierarchies — prefer composition.

## 🔗 Related [#-related]

* [new.md](/docs/javascript/new) — construction
* [objects.md](/docs/javascript/objects) — prototypes & literals
* [properties.md](/docs/javascript/properties) — descriptors
* [map.md](/docs/javascript/map) — WeakMap privacy pattern
* [error.md](/docs/javascript/error) — custom Error subclasses
* [import\_export.md](/docs/javascript/import-export) — exporting classes


---

# Optional Chaining (/docs/javascript/optional-chaining)



# Optional Chaining [#optional-chaining]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Optional chaining (`?.`) short-circuits property/call/element access when the base is `null` or `undefined`, producing `undefined` instead of throwing. Ideal for sparse APIs, optional config, and DOM lookups that may miss.

## 🔧 Core concepts [#-core-concepts]

* **Property**: `obj?.prop`, `obj?.["key"]`.
* **Call**: `fn?.(arg)` — skips call if `fn` is nullish.
* **Element**: `arr?.[0]`.
* **Chain**: `a?.b?.c?.()` — stops at first nullish link.
* **Not a deep existence check for middle truthy holes** — only nullish bases.
* **Assign**: cannot use `?.` on the left-hand side of assignment.

```js
const name = user?.profile?.name;
const first = items?.[0];
api?.log?.("hi");
```

## 💡 Examples [#-examples]

```js
const user = { profile: { name: "Ada" } };
user?.profile?.name; // "Ada"
user?.address?.city; // undefined
null?.x; // undefined

// Methods
const maybe = Math.random() > 0.5 ? console : null;
maybe?.log("ok");

// DOM
document.querySelector("#app")?.classList.add("ready");

// Combined with nullish coalescing
const label = config?.title ?? "Untitled";

// Dynamic key
const key = "email";
user?.contacts?.[key];

// delete with optional (modern)
delete user?.temp; // no-op if user nullish

// Array callback safety
users.map((u) => u.roles?.includes("admin"));
```

```js
// Guard long chains
function getCity(order) {
  return order?.shipping?.address?.city ?? "N/A";
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `?.` only guards `null`/`undefined` — other falsy values (`0`, `""`, `false`) still proceed.
* `obj?.prop` when `obj` exists but `prop` is null returns `null`, not `undefined`.
* Overuse hides bugs — prefer validating required data at boundaries.
* `a?.b.c` still throws if `a.b` is nullish and you access `.c` without `?.`.
* Optional call `fn?.()` does not invent a default function — result is `undefined`.

## 🔗 Related [#-related]

* [nullish\_coalescing.md](/docs/javascript/nullish-coalescing) — `??` defaults
* [destructuring.md](/docs/javascript/destructuring) — defaults on unpack
* [error.md](/docs/javascript/error) — TypeError without `?.`
* [objects.md](/docs/javascript/objects) — property access
* [DOM/selectors.md](/docs/javascript/dom/selectors) — nullable query results


---

# Path (/docs/javascript/path)



# Path [#path]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Node.js `node:path` builds and inspects filesystem paths. Prefer `path.join` / `path.resolve` over string concatenation so separators and `..` segments stay correct across platforms.

```js
import path from "node:path";
```

## 🔧 Core concepts [#-core-concepts]

* **`join(...parts)`**: concatenates segments; normalizes `.` / `..`; does not resolve against cwd.
* **`resolve(...parts)`**: produces an absolute path from right to left; uses `process.cwd()` when needed.
* **`dirname` / `basename` / `extname`**: parent dir, final segment, and extension (including the dot).
* **`parse` / `format`**: object with `root`, `dir`, `base`, `name`, `ext`.
* **`sep`**: `\` on Windows, `/` on POSIX.
* **`path.posix` / `path.win32`**: force POSIX or Windows rules regardless of host OS (useful for URLs or cross-platform config).

## 💡 Examples [#-examples]

```js
import path from "node:path";
import { fileURLToPath } from "node:url";

path.join("logs", "app", "out.txt");
// 'logs/app/out.txt' (POSIX) or 'logs\\app\\out.txt' (win32)

path.resolve("data", "../config.json");
// absolute path ending in config.json

path.dirname("/var/app/index.js"); // '/var/app'
path.basename("/var/app/index.js"); // 'index.js'
path.basename("/var/app/index.js", ".js"); // 'index'
path.extname("photo.tar.gz"); // '.gz'

const p = path.parse("/home/ada/report.pdf");
// { root: '/', dir: '/home/ada', base: 'report.pdf',
//   ext: '.pdf', name: 'report' }

path.format({ dir: "/tmp", base: "a.txt" }); // '/tmp/a.txt'

// ESM __dirname equivalent
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Always forward slashes (e.g. virtual paths)
path.posix.join("a", "b", "c"); // 'a/b/c'
```

## ⚠️ Pitfalls [#️-pitfalls]

* `join` does not make a path absolute; use `resolve` when you need that.
* `extname` returns only the last extension (`.gz` for `a.tar.gz`).
* Mixing `path.win32` and `path.posix` incorrectly breaks joins; pick one style for a given string format.
* Trailing separators are normalized away by `join` / `resolve` (except root).
* Do not use `path` for URL paths — use `URL` / `url` helpers instead.

## 🔗 Related [#-related]

* [Node URL helpers](/docs/javascript/url-node) — `pathToFileURL` / `fileURLToPath`
* [URL](/docs/javascript/url) — WHATWG `URL` in JS
* [CommonJS modules](/docs/javascript/modules-commonjs) — `__dirname` / `__filename`
* [ESM import/export](/docs/javascript/import-export) — `import.meta.url`
* [fs](/docs/javascript/fs) — reading/writing with resolved paths


---

# Performance (/docs/javascript/performance)



# Performance [#performance]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Measure and improve runtime with the Performance APIs: high-res timestamps, marks/measures, resource timing, and observers. Optimize what you measure — long tasks, layout thrash, oversized payloads, and unnecessary main-thread work.

## 🔧 Core concepts [#-core-concepts]

* **`performance.now()`**: monotonic ms since `timeOrigin` (not wall clock).
* **Marks/measures**: `mark`, `measure`, `getEntriesByName`, `clearMarks`.
* **`PerformanceObserver`**: stream entries (`resource`, `paint`, `largest-contentful-paint`, `layout-shift`, `longtask`, `event`, …).
* **Navigation / Resource Timing**: network waterfall data.
* **User Timing**: custom marks for app logic.
* **DevTools**: Performance panel + Lighthouse complement APIs.

```js
performance.mark("start");
work();
performance.mark("end");
performance.measure("work", "start", "end");
```

## 💡 Examples [#-examples]

```js
// Simple timing
const t0 = performance.now();
await doWork();
console.log(performance.now() - t0, "ms");

// Observer for long tasks
const po = new PerformanceObserver((list) => {
  for (const e of list.getEntries()) {
    console.log("longtask", e.duration, e);
  }
});
po.observe({ type: "longtask", buffered: true });

// LCP
new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const last = entries[entries.length - 1];
  console.log("LCP", last.startTime, last.element);
}).observe({ type: "largest-contentful-paint", buffered: true });

// Resource sizes
performance.getEntriesByType("resource").forEach((r) => {
  console.log(r.name, r.transferSize, r.duration);
});

// Avoid layout thrashing
// BAD: read/write interleave forcing reflow
// GOOD: batch reads then writes
const heights = els.map((el) => el.offsetHeight);
els.forEach((el, i) => {
  el.style.height = heights[i] * 2 + "px";
});

// Idle work
requestIdleCallback((deadline) => {
  while (deadline.timeRemaining() > 0 && tasks.length) tasks.pop()();
});
```

```js
// Measure fetch
performance.mark("fetch-start");
const res = await fetch("/api");
performance.mark("fetch-end");
performance.measure("fetch", "fetch-start", "fetch-end");
```

## ⚠️ Pitfalls [#️-pitfalls]

* `Date.now()` can jump with clock changes — use `performance.now()` for durations.
* Observing everything allocates — filter entry types and disconnect when done.
* Micro-benchmarks lie (JIT warmup, DCE) — measure realistic paths.
* Optimizing without profiles wastes time — record a trace first.
* Some entries require HTTPS / specific headers (e.g. server timing, cross-origin detail).

## 🔗 Related [#-related]

* [timers.md](/docs/javascript/timers) — rAF / scheduling
* [event\_loop.md](/docs/javascript/event-loop) — long tasks
* [web\_workers.md](/docs/javascript/web-workers) — offload CPU
* [fetch.md](/docs/javascript/fetch) — network cost
* [DOM/events.md](/docs/javascript/dom/events) — event timing


---

# process (/docs/javascript/process)



# process [#process]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Node.js exposes the current process as the global `process` object: environment, CLI args, working directory, exit codes, and stdio streams. Available without an import in most contexts; you can also `import process from "node:process"`.

## 🔧 Core concepts [#-core-concepts]

* **`process.env`**: environment variables (strings or `undefined`).
* **`process.argv`**: `[nodePath, scriptPath, ...args]`.
* **`process.cwd()`**: current working directory (not the script’s folder).
* **`process.exit(code?)`**: end process; `0` success, non-zero failure.
* **`stdin` / `stdout` / `stderr`**: readable/writable streams for I/O.
* **Signals / events**: `process.on("SIGINT", ...)`, `beforeExit`, `uncaughtException` (use sparingly).

## 💡 Examples [#-examples]

```js
import process from "node:process";

// CLI: node app.js --port 9000
const args = process.argv.slice(2);
console.log(process.execPath); // node binary
console.log(process.cwd());

const port = process.env.PORT ?? "9000";

process.stdout.write("hello\n");
console.error("to stderr"); // often process.stderr

// Read stdin (piped input)
async function readStdin() {
  const chunks = [];
  for await (const chunk of process.stdin) chunks.push(chunk);
  return Buffer.concat(chunks).toString("utf8");
}

process.on("SIGINT", () => {
  console.log("shutting down…");
  process.exit(0);
});

if (!process.env.REQUIRED) {
  console.error("REQUIRED is missing");
  process.exit(1);
}
```

```js
// Change cwd (affects relative fs paths)
process.chdir("/tmp");
```

## ⚠️ Pitfalls [#️-pitfalls]

* `process.exit()` skips pending I/O and `finally` cleanup; prefer letting the loop drain or use `exitCode = 1`.
* `cwd()` is where you launched the process, not `__dirname` / `import.meta.url`.
* `argv` includes node and script paths — slice from index `2` for user args.
* Mutating `process.env` affects the current process only (not the parent shell).
* Unhandled promise rejections may terminate Node depending on version/flags.

## 🔗 Related [#-related]

* [dotenv](/docs/javascript/dotenv) — load `.env` into `process.env`
* [Path](/docs/javascript/path) — resolve paths relative to cwd
* [Stream](/docs/javascript/stream) — stdin/stdout as streams
* [child\_process](/docs/javascript/child-process) — spawn subprocesses
* [Buffer](/docs/javascript/buffer) — binary stdin chunks


---

# Promise (/docs/javascript/promise)



# Promise [#promise]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

A Promise represents a future settlement: pending → fulfilled or rejected. Chain with `then` / `catch` / `finally`, or use `async`/`await`. Combinators coordinate multiple promises.

## 🔧 Core concepts [#-core-concepts]

* **Create**: `new Promise((resolve, reject) => \{ ... \})`, `Promise.resolve`, `Promise.reject`.
* **Consume**: `then(onFulfilled, onRejected)`, `catch`, `finally`.
* **Combinators**: `all`, `allSettled`, `race`, `any`.
* **Thenables**: objects with a `then` method are assimilated.
* **States**: settled state is immutable; further `resolve`/`reject` ignored.

```js
const p = new Promise((resolve, reject) => {
  setTimeout(() => resolve(42), 100);
});
p.then((v) => console.log(v));
```

## 💡 Examples [#-examples]

```js
// Wrap callback API
function readFile(path) {
  return new Promise((resolve, reject) => {
    fs.readFile(path, (err, data) => (err ? reject(err) : resolve(data)));
  });
}

// Combinators
await Promise.all([fetchA(), fetchB()]); // fail-fast
await Promise.allSettled([fetchA(), fetchB()]); // wait all
await Promise.race([fetch(url), timeout(5000)]); // first settled
await Promise.any([mirror1(), mirror2()]); // first fulfilled

// Timeout helper
function timeout(ms) {
  return new Promise((_, reject) => {
    setTimeout(() => reject(new Error("timeout")), ms);
  });
}

// finally for cleanup
fetch(url)
  .then((r) => r.json())
  .finally(() => hideSpinner());

// Flattening
Promise.resolve(1)
  .then((n) => n + 1)
  .then((n) => Promise.resolve(n * 2))
  .then(console.log); // 4
```

```js
// Avoid classic constructor anti-pattern when you already have a promise
// bad: new Promise((resolve) => fetch(url).then(resolve))
// good: return fetch(url)

// Unhandled rejection — always catch
queueMicrotask(() => {
  Promise.reject(new Error("oops")).catch(console.error);
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* `Promise.all` rejects on the first failure — use `allSettled` for partial results.
* Forgetting `return` inside `then` breaks the chain.
* Creating promises that never settle leaks resources — pair with AbortSignal.
* `then(fn, fn)` vs `.catch`: errors in `onFulfilled` skip the second arg — prefer `.catch`.
* Mixing callbacks and promises without wrapping causes double-resolve bugs.

## 🔗 Related [#-related]

* [async.md](/docs/javascript/async) — async/await
* [fetch.md](/docs/javascript/fetch) — promise-based HTTP
* [error.md](/docs/javascript/error) — rejection causes
* [api.md](/docs/javascript/api) — microtasks / AbortSignal
* [iteration.md](/docs/javascript/iteration) — async iteration
* [import\_export.md](/docs/javascript/import-export) — dynamic import()


---

# Properties (/docs/javascript/properties)



# Properties [#properties]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

Object properties have **descriptors** controlling writability, enumerability, configurability, and accessors. Understanding descriptors explains getters, `Object.defineProperty`, and class fields.

## 🔧 Core concepts [#-core-concepts]

* **Data descriptor**: `value`, `writable`, `enumerable`, `configurable`.
* **Accessor descriptor**: `get`, `set`, `enumerable`, `configurable`.
* **Define**: `Object.defineProperty`, `Object.defineProperties`.
* **Inspect**: `Object.getOwnPropertyDescriptor`, `Object.getOwnPropertyDescriptors`.
* **Flags**: non-writable / non-configurable lock down APIs.
* **Symbols**: can be keys; often non-enumerable by convention.

```js
Object.defineProperty(obj, "id", {
  value: 1,
  writable: false,
  enumerable: true,
  configurable: false,
});
```

## 💡 Examples [#-examples]

```js
const user = {};

Object.defineProperty(user, "name", {
  value: "Ada",
  writable: true,
  enumerable: true,
  configurable: true,
});

// Accessor
Object.defineProperty(user, "tag", {
  get() {
    return `@${this.name.toLowerCase()}`;
  },
  set(v) {
    this.name = String(v).replace(/^@/, "");
  },
  enumerable: true,
});

user.tag = "@Grace";
console.log(user.name); // Grace

// Multiple
Object.defineProperties(user, {
  role: { value: "admin", enumerable: true },
  createdAt: { value: Date.now(), writable: false },
});

// Class equivalent
class Rect {
  #w;
  constructor(w, h) {
    this.#w = w;
    this.height = h;
  }
  get width() {
    return this.#w;
  }
  get area() {
    return this.#w * this.height;
  }
}

// Copy descriptors (not just values)
const clone = Object.defineProperties(
  {},
  Object.getOwnPropertyDescriptors(user),
);
```

```js
// Prevent extensions
Object.preventExtensions(user);
Object.seal(user); // + non-configurable
Object.freeze(user); // + non-writable data props
```

## ⚠️ Pitfalls [#️-pitfalls]

* Assignment silently fails on non-writable props in non-strict mode; throws in strict.
* You cannot mix `value` and `get`/`set` in one descriptor.
* `configurable: false` prevents deleting or redefining later.
* Spread/`Object.assign` copy **enumerable values**, not getters as accessors.
* Class fields are writable/enumerable on the instance by default (not on prototype).

## 🔗 Related [#-related]

* [objects.md](/docs/javascript/objects) — object basics
* [oop.md](/docs/javascript/oop) — class getters/fields
* [new.md](/docs/javascript/new) — instance creation
* [map.md](/docs/javascript/map) — alternative key storage
* [json.md](/docs/javascript/json) — enumerable own props only


---

# Prototypes (/docs/javascript/prototypes)



# Prototypes [#prototypes]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

JavaScript inheritance is prototype-based. Every object has an internal `[[Prototype]]` link (exposed as `__proto__` / `Object.getPrototypeOf`). Property lookup walks the chain until found or `null`. Classes are syntax sugar over constructor functions and prototypes.

## 🔧 Core concepts [#-core-concepts]

* **Prototype chain**: `obj` → `Object.getPrototypeOf(obj)` → … → `null`.
* **Own vs inherited**: `hasOwnProperty` / `Object.hasOwn` vs chain lookup.
* **Constructor**: `Fn.prototype` is assigned as `[[Prototype]]` of `new Fn()` instances.
* **`Object.create(proto)`**: make an object with a chosen prototype.
* **Class**: `class C extends B` wires `C.prototype` → `B.prototype`.
* **`new.target`**: detects construct calls.

```js
const proto = { greet() { return "hi"; } };
const obj = Object.create(proto);
obj.greet(); // "hi"
```

## 💡 Examples [#-examples]

```js
function Animal(name) {
  this.name = name;
}
Animal.prototype.speak = function () {
  return `${this.name} makes a noise`;
};

function Dog(name) {
  Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.speak = function () {
  return `${this.name} barks`;
};

const d = new Dog("Rex");
d.speak(); // "Rex barks"
d instanceof Dog; // true
d instanceof Animal; // true

// Modern equivalent
class Cat extends Animal {
  speak() {
    return `${this.name} meows`;
  }
}

// Inspect
Object.getPrototypeOf(d) === Dog.prototype;
Object.hasOwn(d, "name"); // true
Object.hasOwn(d, "speak"); // false

// Null-prototype map (no inherited keys)
const dict = Object.create(null);
dict.admin = true;
"toString" in dict; // false

// Static vs instance
class Mathy {
  static dual(n) {
    return n * 2;
  }
  half() {
    return this.value / 2;
  }
}
```

```js
// Shadowing
const a = Object.create({ x: 1 });
a.x = 2; // own property shadows prototype
delete a.x; // reveals prototype x again
```

## ⚠️ Pitfalls [#️-pitfalls]

* Mutating built-in prototypes (`Array.prototype`) breaks libraries — avoid in app code.
* `for...in` enumerates enumerable inherited keys — prefer `Object.keys` / `hasOwn`.
* Setting `__proto__` is legacy; use `Object.setPrototypeOf` sparingly (engine deopts).
* `instanceof` can fail across realms/iframes with different globals.

## 🔗 Related [#-related]

* [oop.md](/docs/javascript/oop) — class syntax
* [objects.md](/docs/javascript/objects) — property model
* [new.md](/docs/javascript/new) — construction
* [this\_keyword.md](/docs/javascript/this-keyword) — method receivers
* [proxy\_reflect.md](/docs/javascript/proxy-reflect) — intercepting lookup


---

# Proxy & Reflect (/docs/javascript/proxy-reflect)



# Proxy & Reflect [#proxy--reflect]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`Proxy` wraps a target object and intercepts fundamental operations (get, set, apply, construct, …) via traps. `Reflect` mirrors those operations as functions and returns boolean success flags — use it inside traps to forward default behavior correctly.

## 🔧 Core concepts [#-core-concepts]

| Trap                                          | Intercepts                  |
| --------------------------------------------- | --------------------------- |
| `get` / `set`                                 | property read/write         |
| `has`                                         | `in` operator               |
| `deleteProperty`                              | `delete`                    |
| `ownKeys`                                     | `Object.keys` / spread keys |
| `getOwnPropertyDescriptor` / `defineProperty` | descriptors                 |
| `apply` / `construct`                         | function call / `new`       |
| `getPrototypeOf` / `setPrototypeOf`           | prototype                   |

* **Invariants**: traps must respect target non-configurable / non-writable constraints or throw.
* **Revocable**: `Proxy.revocable(target, handler)` → `\{ proxy, revoke \}`.

```js
const p = new Proxy(
  {},
  {
    get(t, prop, receiver) {
      return Reflect.get(t, prop, receiver);
    },
  },
);
```

## 💡 Examples [#-examples]

```js
// Default values
const defaults = { theme: "light" };
const config = new Proxy(defaults, {
  get(t, prop, r) {
    return prop in t ? Reflect.get(t, prop, r) : "«missing»";
  },
});

// Validation on set
const user = new Proxy(
  { age: 0 },
  {
    set(t, prop, value, r) {
      if (prop === "age" && (!Number.isInteger(value) || value < 0)) {
        throw new TypeError("invalid age");
      }
      return Reflect.set(t, prop, value, r);
    },
  },
);

// Negative array index
function wrapArray(arr) {
  return new Proxy(arr, {
    get(t, prop, r) {
      if (typeof prop === "string" && /^-?\d+$/.test(prop)) {
        let i = Number(prop);
        if (i < 0) i = t.length + i;
        return Reflect.get(t, String(i), r);
      }
      return Reflect.get(t, prop, r);
    },
  });
}
wrapArray([1, 2, 3])[-1]; // 3

// Revoke access
const { proxy, revoke } = Proxy.revocable({ secret: 1 }, {});
revoke();
// proxy.secret → TypeError

// Observable-ish
function observable(obj, onChange) {
  return new Proxy(obj, {
    set(t, p, v, r) {
      const ok = Reflect.set(t, p, v, r);
      if (ok) onChange(p, v);
      return ok;
    },
  });
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting `Reflect` / wrong `receiver` breaks inheritance and accessors (`this` in getters).
* Violating invariants (e.g. reporting a non-configurable missing property) throws.
* Proxies are not deeply transparent — `===` identity differs from target; libraries may reject them.
* Performance cost vs plain objects — don’t proxy hot paths without need.
* `typeof proxy` follows the target (object/function).

## 🔗 Related [#-related]

* [objects.md](/docs/javascript/objects) — property model
* [prototypes.md](/docs/javascript/prototypes) — prototype ops
* [symbol.md](/docs/javascript/symbol) — well-known symbols
* [freeze\_seal.md](/docs/javascript/freeze-seal) — hardening without Proxy
* [oop.md](/docs/javascript/oop) — classes vs interception


---

# Regular Expressions (/docs/javascript/regex)



# Regular Expressions [#regular-expressions]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Regular expressions match and extract text patterns. Create with `/pattern/flags` or `new RegExp(string, flags)`. Use with `String` methods (`match`, `matchAll`, `replace`, `search`, `split`) and `RegExp` methods (`test`, `exec`). Prefer readable patterns; escape user input when building dynamic regexes.

## 🔧 Core concepts [#-core-concepts]

| Flag | Meaning                   |
| ---- | ------------------------- |
| `g`  | global — find all         |
| `i`  | ignore case               |
| `m`  | `^`/`$` per line          |
| `s`  | `.` matches newline       |
| `u`  | Unicode (code points)     |
| `y`  | sticky — from `lastIndex` |
| `d`  | indices for groups        |
| `v`  | Unicode sets (modern)     |

* **Groups**: `(...)` capturing, `(?:...)` non-capturing, `(?<name>...)` named.
* **Lookaround**: `(?=...)`, `(?!...)`, `(?&lt;=...)`, `(?&lt;!...)`.
* **Quantifiers**: `*`, `+`, `?`, `\{n,m\}` — add `?` for lazy.
* **Classes**: `\d` `\w` `\s`, `[a-z]`, `[^...]`.

```js
const re = /\b\w+@\w+\.\w+\b/gi;
re.test("a@b.co"); // true
```

## 💡 Examples [#-examples]

```js
// exec loop (mind lastIndex with /g)
const re = /(\d+)/g;
let m;
while ((m = re.exec("a12 b34"))) {
  console.log(m[1], m.index);
}

// matchAll (preferred)
for (const m of "a12 b34".matchAll(/(\d+)/g)) {
  console.log(m[1]);
}

// Named groups + replace
const date = "2026-07-10";
const { groups } = date.match(/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/);
// groups.y === "2026"

"hello world".replace(/(\w+)\s+(\w+)/, "$2 $1"); // "world hello"
"price: 5".replace(/(?<n>\d+)/, "$$$<n>"); // careful with $

// Escape user input
function escapeRegExp(s) {
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
new RegExp(`^${escapeRegExp(user)}.txt$`);

// Unicode
/\p{Emoji}/u.test("😀"); // true
```

```js
// Validation
const emailish = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
emailish.test("dev@example.com");
```

## ⚠️ Pitfalls [#️-pitfalls]

* `/g` regexes keep `lastIndex` — reuse can skip matches; reset or use `matchAll`.
* Dot `.` does not match newlines unless `s` flag.
* Catastrophic backtracking on crafted input — avoid nested ambiguous quantifiers on untrusted strings.
* `new RegExp("\\d")` needs double escaping vs literals.
* `replace` with a string treats `$&`, `$1`, etc. specially.

## 🔗 Related [#-related]

* [strings.md](/docs/javascript/strings) — string APIs
* [template\_literals.md](/docs/javascript/template-literals) — building patterns
* [encode.md](/docs/javascript/encode) — encoding vs matching
* [error.md](/docs/javascript/error) — SyntaxError on bad patterns


---

# Set (/docs/javascript/set)



# Set [#set]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`Set` stores unique values using SameValueZero equality. Insertion order is preserved. Use sets for membership tests, deduplication, and set-algebra helpers.

## 🔧 Core concepts [#-core-concepts]

* **Create**: `new Set()`, `new Set(iterable)`.
* **Mutate**: `add`, `delete`, `clear`, `has`.
* **Size**: `set.size`.
* **Iterate**: `keys()` / `values()` (same), `entries()` → `[v, v]`, `forEach`, `for...of`.
* **Equality**: `NaN` equals `NaN`; objects by reference.

```js
const s = new Set([1, 2, 2, 3]);
s.size; // 3
s.has(2); // true
```

## 💡 Examples [#-examples]

```js
// Deduplicate array
const unique = [...new Set(items)];

// Membership
const allowed = new Set(["read", "write", "admin"]);
if (allowed.has(role)) { /* ... */ }

// Union / intersection / difference (ES2025 methods where available)
function union(a, b) {
  return new Set([...a, ...b]);
}
function intersection(a, b) {
  return new Set([...a].filter((x) => b.has(x)));
}
function difference(a, b) {
  return new Set([...a].filter((x) => !b.has(x)));
}

// Native (modern engines)
// a.union(b); a.intersection(b); a.difference(b); a.symmetricDifference(b);

// Toggle membership
function toggle(set, value) {
  if (set.has(value)) set.delete(value);
  else set.add(value);
  return set;
}

// WeakSet — objects only, not iterable
const seen = new WeakSet();
function visit(node) {
  if (seen.has(node)) return;
  seen.add(node);
}
```

```js
for (const v of s) console.log(v);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Object uniqueness is by reference: `new Set([\{a:1\},\{a:1\}]).size === 2`.
* `JSON.stringify(set)` → `"\{\}"` — convert with `[...set]` first.
* `set[0]` does not work — use iteration or convert to array.
* `WeakSet` cannot hold primitives and is not enumerable.
* Mutating while iterating is allowed but can be confusing — prefer snapshots.

## 🔗 Related [#-related]

* [map.md](/docs/javascript/map) — Map collections
* [arrays.md](/docs/javascript/arrays) — dedupe patterns
* [iteration.md](/docs/javascript/iteration) — looping sets
* [for\_of.md](/docs/javascript/for-of) — for...of
* [objects.md](/docs/javascript/objects) — reference equality
* [json.md](/docs/javascript/json) — serialization limits


---

# Spread & Rest (/docs/javascript/spread-rest)



# Spread & Rest [#spread--rest]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`...` is rest when collecting values into an array/object, and spread when expanding an iterable or object into places that expect multiple elements/properties. Same syntax, opposite direction — context decides.

## 🔧 Core concepts [#-core-concepts]

* **Rest (collect)**: function params, array/object destructuring — must be last.
* **Spread (expand)**: call args, array literals, object literals (own enumerable props).
* **Arrays/iterables**: spread uses the iterator protocol.
* **Objects**: shallow copy / merge — later keys win.
* **Clone caveats**: spread is shallow; nested objects stay shared by reference.

```js
const nums = [1, 2, 3];
Math.max(...nums); // 3
const copy = [...nums];
const merged = { ...a, ...b };
```

## 💡 Examples [#-examples]

```js
// Rest parameters
function logAll(label, ...items) {
  console.log(label, items);
}
logAll("ids", 1, 2, 3); // items === [1, 2, 3]

// Spread into call
const args = [10, 20];
sum(...args);

// Concat / insert
const a = [1, 2];
const b = [0, ...a, 3]; // [0, 1, 2, 3]

// Copy Set / NodeList
const unique = [...new Set([1, 1, 2])];
const els = [...document.querySelectorAll("li")];

// Object merge (shallow)
const defaults = { theme: "light", lang: "en" };
const prefs = { theme: "dark" };
const config = { ...defaults, ...prefs }; // theme: "dark"

// Rest in destructuring
const [head, ...tail] = [1, 2, 3, 4];
const { id, ...meta } = { id: 1, name: "x", role: "admin" };

// Spread Map entries into object (string keys)
const m = new Map([["a", 1], ["b", 2]]);
const obj = Object.fromEntries(m);
```

```js
// Immutable update pattern
const state = { user: { name: "Ada" }, count: 0 };
const next = { ...state, count: state.count + 1 };
```

## ⚠️ Pitfalls [#️-pitfalls]

* Object spread does not copy inherited or non-enumerable properties; symbols need care.
* Spreading huge arrays into args can hit call-stack / argument limits — use loops.
* `...null` / `...undefined` in objects is a no-op; in arrays they throw.
* Rest in objects excludes the listed keys but does not deep-clone nested values.
* Spread order matters for overrides: put overrides last.

## 🔗 Related [#-related]

* [destructuring.md](/docs/javascript/destructuring) — rest patterns
* [arrays.md](/docs/javascript/arrays) — array copy/concat
* [objects.md](/docs/javascript/objects) — object assign/merge
* [functions.md](/docs/javascript/functions) — rest params
* [iterator.md](/docs/javascript/iterator) — iterable protocol


---

# Stream (/docs/javascript/stream)



# Stream [#stream]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Node.js streams process data in chunks instead of loading everything into memory. Core types: **Readable**, **Writable**, **Duplex**, **Transform**. Prefer `pipeline` (or `stream/promises`) for error-safe piping.

```js
import { pipeline } from "node:stream/promises";
import { createReadStream, createWriteStream } from "node:fs";
```

## 🔧 Core concepts [#-core-concepts]

* **Readable**: producers (`fs.createReadStream`, HTTP request body). Modes: flowing vs paused.
* **Writable**: consumers (`fs.createWriteStream`, HTTP response). Backpressure via `write()` return value.
* **`pipe` / `pipeline`**: connect readable → writable (and transforms). `pipeline` destroys streams on error and forwards errors.
* **Transform**: duplex that modifies chunks (gzip, cipher, line splitters).
* **Object mode**: streams of objects instead of Buffers/strings (`objectMode: true`).
* **Events**: `data`, `end`, `error`, `finish`, `readable` (EventEmitter-based).

## 💡 Examples [#-examples]

```js
import { createReadStream, createWriteStream } from "node:fs";
import { pipeline } from "node:stream/promises";
import { createGzip } from "node:zlib";

await pipeline(
  createReadStream("big.txt"),
  createGzip(),
  createWriteStream("big.txt.gz"),
);

// Manual consume (async iterator)
import { createReadStream as rs } from "node:fs";
for await (const chunk of rs("log.txt", { encoding: "utf8" })) {
  process.stdout.write(chunk);
}
```

```js
import { Readable, Transform } from "node:stream";

const src = Readable.from(["a\n", "b\n", "c\n"]);
const upper = new Transform({
  transform(chunk, enc, cb) {
    cb(null, chunk.toString().toUpperCase());
  },
});

await pipeline(src, upper, process.stdout);
```

```js
// Backpressure sketch
function writeAll(writable, chunks) {
  let i = 0;
  function write() {
    for (; i < chunks.length; i++) {
      const ok = writable.write(chunks[i]);
      if (!ok) {
        writable.once("drain", write);
        return;
      }
    }
    writable.end();
  }
  write();
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Classic `.pipe()` does not clean up well on errors — use `pipeline`.
* Ignoring `error` events can crash the process.
* Mixing `data` handlers and async iteration can conflict — pick one consumption style.
* Forgetting `end()` on writables leaves pipelines hanging.
* Buffering entire stream into a string defeats the purpose for large files.

## 🔗 Related [#-related]

* [fs](/docs/javascript/fs) — file streams vs `readFile`
* [Events](/docs/javascript/events-node) — EventEmitter under streams
* [Buffer](/docs/javascript/buffer) — binary chunks
* [Async](/docs/javascript/async) — `for await` of readables
* [fetch](/docs/javascript/fetch) — web streams / response bodies
* [child\_process](/docs/javascript/child-process) — stdio streams


---

# Strict Mode (/docs/javascript/strict-mode)



# Strict Mode [#strict-mode]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Strict mode (`"use strict"`) opts into a cleaner, safer JavaScript subset: fewer silent failures, no accidental globals, and `this` is `undefined` in bare calls. ES modules and class bodies are strict by default.

## 🔧 Core concepts [#-core-concepts]

* **Enable**: `"use strict";` at top of script or function body.
* **Modules / classes**: always strict.
* **No accidental globals**: assigning undeclared vars throws.
* **`this`**: `undefined` in non-method calls (not global object).
* **Forbidden**: `with`, octal literals like `0123`, deleting plain names, duplicate params (legacy).
* **`arguments`**: no dynamic link to parameters; `arguments.callee` forbidden.

```js
"use strict";
function f() {
  return this; // undefined when called as f()
}
```

## 💡 Examples [#-examples]

```js
"use strict";

// ReferenceError — would create global in sloppy mode
// x = 1;

let x = 1;
// delete x; // SyntaxError in strict

function sum(a, a) {
  // SyntaxError: duplicate params in strict
}

function show() {
  console.log(this);
}
show(); // undefined (strict) vs window (sloppy browser)

// Silent failure becomes throw
const obj = Object.freeze({ a: 1 });
// obj.a = 2; // TypeError in strict

// Octal
// const n = 012; // SyntaxError — use 0o12

// eval/arguments as binding names illegal
// function eval() {} // SyntaxError
```

```js
// Function-level strict
function legacyCompat() {
  // sloppy if script is sloppy
}
function modern() {
  "use strict";
  // strict only inside modern
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Concatenating scripts can lose a leading `"use strict"` if not first statement.
* Libraries expecting sloppy `this === window` break under strict — bind explicitly.
* Strict is per-function/script — mixed modes in one bundle confuse debugging.
* Don’t rely on sloppy features; write as if everything is strict (modules already are).

## 🔗 Related [#-related]

* [this\_keyword.md](/docs/javascript/this-keyword) — undefined this
* [import\_export.md](/docs/javascript/import-export) — modules are strict
* [error.md](/docs/javascript/error) — thrown errors
* [freeze\_seal.md](/docs/javascript/freeze-seal) — TypeError on mutate
* [equality.md](/docs/javascript/equality) — cleaner semantics


---

# Strings (/docs/javascript/strings)



# Strings [#strings]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

Strings are immutable UTF-16 sequences. Prefer template literals, `includes`/`startsWith`, and `replaceAll` over older index loops. For full Unicode graphemes, be aware of code units vs code points.

## 🔧 Core concepts [#-core-concepts]

**Create / access**

| API                                    | Notes                               |
| -------------------------------------- | ----------------------------------- |
| `'...'`, `"..."`, `` `tmpl $\{x\}` ``  | Prefer templates for interpolation  |
| `String(x)`, `String.raw`…\`\`         | Coerce; raw skips escape processing |
| `str.length`                           | UTF-16 **code units**               |
| `str[i]`, `str.at(i)`, `str.charAt(i)` | `at` supports negatives             |
| `charCodeAt` / `codePointAt`           | Unit vs full code point             |

**Search / match**

| Method                    | Notes                                   |
| ------------------------- | --------------------------------------- |
| `includes(sub, from?)`    | Boolean substring                       |
| `indexOf` / `lastIndexOf` | Index or `-1`                           |
| `startsWith` / `endsWith` | Prefix / suffix (pos optional)          |
| `search(re)`              | First regex match index                 |
| `match(re)`               | Match array or `null`                   |
| `matchAll(re)`            | Iterator of all matches (`/g` required) |

**Slice / split / join**

| Method                   | Notes                          |
| ------------------------ | ------------------------------ |
| `slice(start?, end?)`    | Supports negatives; preferred  |
| `substring(a, b)`        | Swaps if `a > b`; no negatives |
| `substr(start, len)`     | Legacy — avoid                 |
| `split(sep\|re, limit?)` | → array; empty sep → chars     |
| `Array` `.join(sep)`     | Inverse of `split`             |

**Case / trim / pad / repeat**

| Method                             | Notes                 |
| ---------------------------------- | --------------------- |
| `toLowerCase` / `toUpperCase`      | Locale-insensitive    |
| `toLocaleLowerCase` / `…UpperCase` | Locale-aware          |
| `trim` / `trimStart` / `trimEnd`   | Whitespace (Unicode)  |
| `padStart(n, fill?)` / `padEnd`    | Pad to length `n`     |
| `repeat(n)`                        | Concatenate `n` times |

**Replace / normalize / unicode**

| Method                                  | Notes                                   |
| --------------------------------------- | --------------------------------------- |
| `replace(pat, rep\|fn)`                 | First match only if string/`/g` missing |
| `replaceAll(pat, rep\|fn)`              | All; string or global regex             |
| `normalize("NFC"\|"NFD"\|…)`            | Unicode normalization forms             |
| `localeCompare(other, locales?, opts?)` | Collation compare → −1/0/1              |
| `for...of str`                          | Iterates **code points**                |
| `[...str]` / `Array.from(str)`          | Code-point array                        |

```js
const name = "Ada";
`Hello, ${name}!`;
"file.js".endsWith(".js"); // true
```

## 💡 Examples [#-examples]

```js
const s = "  Hello, World  ";
s.trim().toLowerCase(); // "hello, world"
"a-b-c".split("-"); // ["a","b","c"]
"na".repeat(3); // "nanana"
"id".padStart(4, "0"); // "00id"
"foo bar foo".replaceAll("foo", "baz");

// Template multiline
const html = `
  <div class="card">
    ${title}
  </div>
`.trim();

// Code points iteration
for (const ch of "A🙂B") console.log(ch);

// matchAll
const re = /\d+/g;
for (const m of "a1 b23".matchAll(re)) {
  console.log(m[0], m.index);
}

// Slice vs substring
"abcdef".slice(1, -1); // "bcde"
"abcdef".substring(1, 4); // "bcd"

// Normalize Unicode
"é".normalize("NFC");
```

```js
// Safe HTML escape (minimal)
function escapeHtml(str) {
  return str
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;");
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Strings are immutable — methods return new strings.
* `replace` with string pattern replaces only the first match — use `replaceAll` or `/g`.
* Surrogate pairs: `"🙂".length === 2`; prefer `for...of` / `codePointAt`.
* `==` coerces; compare with `===`.
* Building HTML via concatenation risks XSS — escape or use DOM APIs / frameworks.

## 🔗 Related [#-related]

* [encode.md](/docs/javascript/encode) — URI encoding
* [boolean.md](/docs/javascript/boolean) — empty string falsy
* [arrays.md](/docs/javascript/arrays) — split/join
* [json.md](/docs/javascript/json) — string escaping
* [for\_of.md](/docs/javascript/for-of) — iterating characters
* [DOM/content\_methods.md](/docs/javascript/dom/content-methods) — text vs HTML


---

# Structured Clone (/docs/javascript/structured-clone)



# Structured Clone [#structured-clone]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The structured clone algorithm deep-copies certain JS values across realms — used by `structuredClone()`, `postMessage`, IndexedDB, and history state. It handles built-ins that `JSON` cannot (Dates, Maps, typed arrays) but rejects functions, DOM nodes, and symbols as keys in some cases.

## 🔧 Core concepts [#-core-concepts]

* **API**: `structuredClone(value, \{ transfer \})`.
* **Supported**: primitives, plain objects/arrays, `Date`, `RegExp`, `Map`, `Set`, `Blob`, `File`, `ArrayBuffer`, typed arrays, `Error` (mostly), cyclic refs.
* **Unsupported**: functions, DOM nodes, class instances’ methods / prototype identity, some platform objects.
* **Transfer**: move `ArrayBuffer` ownership (detached source) via `transfer` list.
* **vs JSON**: JSON drops `undefined`, converts Date to string, can’t cycle; clone keeps more types.

```js
const copy = structuredClone({ d: new Date(), m: new Map([[1, 2]]) });
copy.d instanceof Date; // true
```

## 💡 Examples [#-examples]

```js
// Deep clone with cycles
const a = { name: "a" };
a.self = a;
const b = structuredClone(a);
b.self === b; // true
b !== a; // true

// Map / Set
structuredClone(new Set([1, 2, 2]));

// Transfer buffer to worker-like flow
const buf = new ArrayBuffer(8);
const moved = structuredClone(buf, { transfer: [buf] });
// buf.byteLength === 0 (detached)

// postMessage uses same algorithm
worker.postMessage({ pixels }, [pixels.buffer]);

// History state
history.pushState(structuredClone(state), "", url);

// What fails
// structuredClone(() => {}); // DataCloneError
// structuredClone(document.body); // DataCloneError

// JSON fallback comparison
JSON.parse(JSON.stringify({ d: new Date() })).d; // string, not Date
```

```js
// Clone error
const err = structuredClone(new Error("boom"));
err.message; // "boom"
```

## ⚠️ Pitfalls [#️-pitfalls]

* Class instances become plain objects (prototype lost) or throw — don’t expect methods.
* `transfer` detaches the original buffer — subsequent access throws.
* Older browsers need polyfills / fallbacks for `structuredClone`.
* `WeakMap` / functions / symbols as object keys are not cloneable.
* Not a security boundary by itself — still validate untrusted data.

## 🔗 Related [#-related]

* [json.md](/docs/javascript/json) — JSON clone limits
* [web\_workers.md](/docs/javascript/web-workers) — postMessage
* [typed\_arrays.md](/docs/javascript/typed-arrays) — transferable buffers
* [history\_api.md](/docs/javascript/history-api) — pushState data
* [freeze\_seal.md](/docs/javascript/freeze-seal) — immutability after clone


---

# switch / case (/docs/javascript/switch-case)



# switch / case [#switch--case]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`switch` selects a branch by strict equality (`===`) against a discriminant. Cases fall through until `break`, `return`, or `throw`. Prefer maps/objects or early returns when branches share little structure.

## 🔧 Core concepts [#-core-concepts]

* **Syntax**: `switch (expr) \{ case v: ... break; default: ... \}`.
* **Matching**: strict equality; no pattern matching built-in.
* **Fall-through**: intentional sharing of bodies; always comment intentional fall-through.
* **Scope**: wrap case bodies in `\{ \}` when using `let`/`const` to avoid TDZ clashes.
* **Alternatives**: lookup tables, `Map`, if/else chains, pattern libs.

```js
switch (status) {
  case 200:
    return "ok";
  case 404:
    return "missing";
  default:
    return "other";
}
```

## 💡 Examples [#-examples]

```js
function httpLabel(code) {
  switch (code) {
    case 200:
    case 201:
    case 204:
      return "success";
    case 301:
    case 302:
      return "redirect";
    case 400:
    case 401:
    case 403:
    case 404:
      return "client-error";
    case 500:
      return "server-error";
    default:
      return "unknown";
  }
}

// Block scope per case
switch (kind) {
  case "user": {
    const id = crypto.randomUUID();
    return { kind, id };
  }
  case "guest": {
    const id = "guest";
    return { kind, id };
  }
  default:
    throw new Error(`bad kind: ${kind}`);
}

// Dispatch table
const handlers = {
  ping: () => "pong",
  time: () => Date.now(),
};
const result = (handlers[cmd] ?? (() => "noop"))();

// switch (true) pattern (use sparingly)
switch (true) {
  case score >= 90:
    return "A";
  case score >= 80:
    return "B";
  default:
    return "C";
}
```

```js
// Exhaustiveness helper for unions (manual)
function assertNever(x) {
  throw new Error(`unexpected: ${x}`);
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Missing `break` causes accidental fall-through bugs.
* `case` values are compared with `===` — `"1"` does not match `1`.
* `let`/`const` in a case without braces collide with other cases.
* Large switches are harder to test — prefer strategy maps for open sets of commands.
* `default` is optional but recommended for unexpected values.

## 🔗 Related [#-related]

* [boolean.md](/docs/javascript/boolean) — conditions
* [objects.md](/docs/javascript/objects) — dispatch tables
* [map.md](/docs/javascript/map) — Map-based dispatch
* [error.md](/docs/javascript/error) — default throws
* [oop.md](/docs/javascript/oop) — polymorphic alternatives


---

# Symbol (/docs/javascript/symbol)



# Symbol [#symbol]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`Symbol` is a primitive unique key type. Each `Symbol("desc")` is unique (except `Symbol.for`). Symbols enable non-colliding object properties, protocol hooks (`Symbol.iterator`), and meta behavior without string key clashes.

## 🔧 Core concepts [#-core-concepts]

* **Create**: `Symbol(description?)` — always unique.
* **Global registry**: `Symbol.for(key)` / `Symbol.keyFor(sym)`.
* **As keys**: `obj[sym] = value` — skipped by most string enumerations.
* **Well-known**: `Symbol.iterator`, `Symbol.asyncIterator`, `Symbol.toStringTag`, `Symbol.hasInstance`, `Symbol.toPrimitive`, etc.
* **Description**: `sym.description` (informational only).
* **Not constructible**: `new Symbol()` throws.

```js
const id = Symbol("id");
const user = { [id]: 42, name: "Ada" };
user[id]; // 42
```

## 💡 Examples [#-examples]

```js
const SECRET = Symbol("secret");
const bag = {
  visible: true,
  [SECRET]: "hidden",
};
Object.keys(bag); // ["visible"]
Object.getOwnPropertySymbols(bag); // [Symbol(secret)]

// Global shared symbol
const a = Symbol.for("app.token");
const b = Symbol.for("app.token");
a === b; // true
Symbol.keyFor(a); // "app.token"

// Custom iterable
const range = {
  from: 1,
  to: 3,
  *[Symbol.iterator]() {
    for (let i = this.from; i <= this.to; i++) yield i;
  },
};
[...range]; // [1, 2, 3]

// toStringTag
class Queue {
  get [Symbol.toStringTag]() {
    return "Queue";
  }
}
Object.prototype.toString.call(new Queue()); // "[object Queue]"

// hasInstance
class Even {
  static [Symbol.hasInstance](x) {
    return Number(x) % 2 === 0;
  }
}
2 instanceof Even; // true
```

```js
// Unique enum-like constants
const Color = {
  Red: Symbol("red"),
  Blue: Symbol("blue"),
};
```

## ⚠️ Pitfalls [#️-pitfalls]

* `JSON.stringify` omits symbol keys — serialize explicitly if needed.
* Symbols are not truly private — `getOwnPropertySymbols` reveals them; use `#private` fields for real privacy.
* `Symbol.for` shares across the realm — choose unique registry keys.
* Spreading `\{...obj\}` copies enumerable string keys; symbol copy needs `getOwnPropertySymbols` + descriptors.

## 🔗 Related [#-related]

* [objects.md](/docs/javascript/objects) — property keys
* [iterator.md](/docs/javascript/iterator) — Symbol.iterator
* [oop.md](/docs/javascript/oop) — private fields
* [proxy\_reflect.md](/docs/javascript/proxy-reflect) — ownKeys traps
* [json.md](/docs/javascript/json) — serialization limits


---

# Template Literals Basics (/docs/javascript/template-basics)



# Template Literals Basics [#template-literals-basics]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Template literals are strings wrapped in backticks (`` ` ``). They support interpolation with `$\{...\}` and multi-line text without awkward `+` concatenation.

## 🔧 Core concepts [#-core-concepts]

| Feature          | Syntax                    | Purpose                    |
| ---------------- | ------------------------- | -------------------------- |
| Template         | `` `text` ``              | String with superpowers    |
| Interpolation    | `` `$\{expr\}` ``         | Embed any expression       |
| Multi-line       | Newlines inside backticks | Readable paragraphs        |
| Nested           | Templates inside `$\{\}`  | Advanced formatting        |
| Tagged templates | `tag\`...\`\`             | Advanced (libraries, i18n) |

Prefer templates over `+` when building messages from variables.

## 💡 Examples [#-examples]

**Interpolation:**

```js
const name = "Ada";
const score = 95;
console.log(`Hello, ${name}! Score: ${score}`);
```

**Expressions inside $\{}:**

```js
const a = 3;
const b = 4;
console.log(`${a} + ${b} = ${a + b}`);
console.log(`Upper: ${"hi".toUpperCase()}`);
```

**Multi-line:**

```js
const html = `
<section>
  <h1>Title</h1>
  <p>Hello</p>
</section>
`.trim();
console.log(html);
```

**Compared to concatenation:**

```js
const user = "Sam";
const oldWay = "Hi " + user + "!";
const newWay = `Hi ${user}!`;
console.log(oldWay === newWay); // true
```

## ⚠️ Pitfalls [#️-pitfalls]

* Use backticks `` ` ``, not quotes — `"Hello $\{name\}"` does **not** interpolate.
* Nested quotes are fine inside templates; escaping backticks needs \`\`\`.
* Huge templates with logic become hard to read — extract variables first.
* Accidental leading indentation in multi-line templates is part of the string.

## 🔗 Related [#-related]

* [hello\_world.md](/docs/javascript/hello-world)
* [variables\_let\_const.md](/docs/javascript/variables-let-const)
* [typeof\_basics.md](/docs/javascript/typeof-basics)
* [strings](/docs/javascript/strings)


---

# Template Literals (/docs/javascript/template-literals)



# Template Literals [#template-literals]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Template literals use backticks `` ` `` for strings with interpolation `$\{expr\}`, multi-line text, and tagged templates. They replace most string concatenation and enable DSLs (e.g. sanitizers, CSS-in-JS) via tag functions.

## 🔧 Core concepts [#-core-concepts]

* **Interpolate**: `` `Hello $\{name\}` `` — any expression inside `$\{\}`.
* **Multi-line**: newlines are preserved as written.
* **Escape**: `\``, `$`, `\\\` as needed.
* **Tagged**: `tag\`...\``calls`tag(strings, ...values)\`.
* **Raw**: `String.raw\`C:\path\file\`\` — backslashes mostly literal.
* **Nested**: templates can nest inside `$\{\}`.

```js
const name = "Ada";
const msg = `Hello, ${name}!`;
const block = `line1
line2`;
```

## 💡 Examples [#-examples]

```js
const a = 3,
  b = 4;
`sum=${a + b}`; // "sum=7"

// Expressions
`User: ${user?.name ?? "guest"}`;
`Items: ${items.map((i) => i.id).join(", ")}`;

// HTML snippet (sanitize user input!)
const html = `<li class="item">${escapeHtml(text)}</li>`;

// Tagged template
function highlight(strings, ...values) {
  return strings.reduce(
    (out, str, i) => out + str + (values[i] != null ? `<b>${values[i]}</b>` : ""),
    "",
  );
}
highlight`Hello ${"world"}`; // "Hello <b>world</b>"

// String.raw
String.raw`\n`; // "\\n" (two chars: \ and n)

// Nested
const rows = people.map((p) => `<tr><td>${p.name}</td></tr>`).join("");
const table = `<table>${rows}</table>`;
```

```js
// Dynamic property in message
const key = "count";
`Total ${key}=${data[key]}`;
```

## ⚠️ Pitfalls [#️-pitfalls]

* Interpolating untrusted HTML/SQL causes XSS/injection — escape or use safe APIs.
* `$\{obj\}` becomes `obj.toString()` — often `"[object Object]"`; format explicitly.
* Older engines / some tooling mishandle tagged templates — know your targets.
* Accidental nesting of quotes is fine with backticks, but `$\{` inside needs care.
* Large templates rebuilt every render can allocate heavily — cache static parts.

## 🔗 Related [#-related]

* [strings.md](/docs/javascript/strings) — string methods
* [f-string style](/docs/javascript/strings) — formatting
* [optional\_chaining.md](/docs/javascript/optional-chaining) — in interpolations
* [regex.md](/docs/javascript/regex) — patterns vs templates
* [encode.md](/docs/javascript/encode) — escaping


---

# Ternary Operator (/docs/javascript/ternary)



# Ternary Operator [#ternary-operator]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The conditional (ternary) operator `cond ? then : else` picks one of two expressions. It is an **expression** (produces a value), unlike `if` which is a statement. Use for simple choices; avoid nested ternaries that obscure intent.

## 🔧 Core concepts [#-core-concepts]

* **Form**: `condition ? valueIfTruthy : valueIfFalsy`.
* **Associativity**: right-associative — `a ? b : c ? d : e` ≡ `a ? b : (c ? d : e)`.
* **Precedence**: lower than most operators; higher than assignment and `??`/`||` in careful mixes — use parentheses.
* **Any expressions**: including function calls, objects, further ternaries.
* **Not a substitute** for multi-statement branches — use `if`.

```js
const label = isOn ? "On" : "Off";
const n = x > 0 ? x : 0;
```

## 💡 Examples [#-examples]

```js
// Assignment / return
function fee(amount, member) {
  return member ? amount * 0.9 : amount;
}

// JSX / render-style (conceptually)
const icon = loading ? "spinner" : error ? "warn" : "ok"; // nested — consider clarity

// Prefer flat for readability
const icon2 = loading ? "spinner" : error ? "warn" : "ok";

// With nullish
const title = item?.name ? item.name : "Untitled";
// often better:
const title2 = item?.name ?? "Untitled";

// Call choice
(mode === "edit" ? save : create)(payload);

// Class names
el.className = active ? "tab active" : "tab";

// Nested with parens for clarity
const access =
  user == null ? "guest" : user.isAdmin ? "admin" : "user";
```

```js
// Illegal: statements inside branches without expressions
// cond ? let x = 1 : let y = 2; // SyntaxError
// use if/else or IIFE / blocks in modern proposal contexts carefully
```

## ⚠️ Pitfalls [#️-pitfalls]

* Nested ternaries become unreadable quickly — prefer `if`, lookup maps, or early returns.
* Truthiness: `value ? value : fallback` treats `0`/`""` as missing — use `??`.
* Mixing with `??` / `||` without parentheses is confusing or a syntax error in some combos.
* Side effects in both branches still evaluate only one branch — good — but don’t hide important logic there.
* Overusing ternaries for control flow that needs blocks leads to awkward IIFEs.

## 🔗 Related [#-related]

* [conditionals.md](/docs/javascript/conditionals) — if/else
* [nullish\_coalescing.md](/docs/javascript/nullish-coalescing) — `??`
* [boolean.md](/docs/javascript/boolean) — truthiness
* [optional\_chaining.md](/docs/javascript/optional-chaining) — safe access
* [equality.md](/docs/javascript/equality) — comparisons in conditions


---

# this Keyword (/docs/javascript/this-keyword)



# this Keyword [#this-keyword]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`this` is determined by **how a function is called**, not where it is defined (except arrows, which inherit lexical `this`). Master call-site rules, binding methods, and class fields to avoid the most common JS bugs.

## 🔧 Core concepts [#-core-concepts]

| Call style                | `this`                       |
| ------------------------- | ---------------------------- |
| `obj.method()`            | `obj`                        |
| `fn()` (sloppy)           | global object                |
| `fn()` (strict / modules) | `undefined`                  |
| `new Fn()`                | new instance                 |
| `fn.call/apply/bind`      | explicit                     |
| Arrow function            | lexical outer `this`         |
| DOM handler (classic)     | element (unless arrow/bound) |

* **`bind`**: returns a new function with fixed `this` (and optional partial args).
* **`call` / `apply`**: invoke immediately with chosen `this`.
* **Class methods**: need binding or arrows if passed as callbacks.

```js
const obj = {
  n: 1,
  get() {
    return this.n;
  },
};
obj.get(); // 1
```

## 💡 Examples [#-examples]

```js
"use strict";

function show() {
  return this?.id;
}
const user = { id: 42, show };
user.show(); // 42
show(); // undefined (strict)

// Explicit binding
show.call({ id: 7 }); // 7
const bound = show.bind({ id: 9 });
bound(); // 9

// Losing this
const detached = user.show;
detached(); // undefined

// Arrow preserves outer this
class Counter {
  count = 0;
  inc = () => {
    this.count += 1;
  };
  bump() {
    this.count += 1;
  }
}
const c = new Counter();
setTimeout(c.inc, 0); // OK
setTimeout(c.bump, 0); // broken unless bound

// call vs apply
function greet(a, b) {
  return `${this.name}: ${a} ${b}`;
}
greet.call({ name: "Ada" }, "hi", "there");
greet.apply({ name: "Ada" }, ["hi", "there"]);

// DOM
button.addEventListener("click", function () {
  console.log(this); // button
});
button.addEventListener("click", () => {
  console.log(this); // outer lexical this
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* Extracting methods (`const f = obj.m`) drops the receiver.
* Arrows on prototypes are usually wrong — they close over the wrong `this` at definition time for classes use public fields carefully.
* `bind` creates a new function each time — don’t bind inside render loops without caching.
* In modules, top-level `this` is `undefined`, not `window`.

## 🔗 Related [#-related]

* [functions.md](/docs/javascript/functions) — arrow vs function
* [closures.md](/docs/javascript/closures) — lexical capture
* [oop.md](/docs/javascript/oop) — classes & methods
* [strict\_mode.md](/docs/javascript/strict-mode) — undefined `this`
* [DOM/events.md](/docs/javascript/dom/events) — handler `this`


---

# Timers (/docs/javascript/timers)



# Timers [#timers]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Timers schedule callbacks on the event loop: `setTimeout`, `setInterval`, and animation-oriented `requestAnimationFrame`. Always keep the handle to clear them. Prefer `rAF` for visual work and avoid overlapping intervals for async jobs.

## 🔧 Core concepts [#-core-concepts]

* **`setTimeout(fn, ms, ...args)`**: once after delay; returns timer id.
* **`setInterval(fn, ms, ...args)`**: repeats; drifts under load.
* **`clearTimeout` / `clearInterval`**: cancel by id.
* **`requestAnimationFrame(cb)`**: before next paint; `cb(timestamp)`.
* **`cancelAnimationFrame(id)`**: cancel rAF.
* **Delay clamping**: nested timeouts / background tabs may be throttled (≥4ms, often 1s+ inactive).
* **`scheduler` / `scheduler.postTask`** (where available): prioritized tasks.

```js
const id = setTimeout(() => console.log("later"), 1000);
clearTimeout(id);
```

## 💡 Examples [#-examples]

```js
// Pass arguments
setTimeout(console.log, 0, "hello", 42);

// Recursive timeout (better control than interval)
function poll(ms) {
  let stopped = false;
  async function tick() {
    if (stopped) return;
    await fetchStatus();
    setTimeout(tick, ms);
  }
  tick();
  return () => {
    stopped = true;
  };
}

// Interval with cleanup
const id = setInterval(() => {
  console.log(Date.now());
}, 1000);
// later: clearInterval(id);

// Animation loop
let raf;
function loop(t) {
  draw(t);
  raf = requestAnimationFrame(loop);
}
raf = requestAnimationFrame(loop);
// cancelAnimationFrame(raf);

// Debounce with timeout
function debounce(fn, ms) {
  let t;
  return (...args) => {
    clearTimeout(t);
    t = setTimeout(() => fn(...args), ms);
  };
}

// Promise wrapper
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
await sleep(200);
```

```js
// Abortable sleep
function sleep(ms, signal) {
  return new Promise((resolve, reject) => {
    const t = setTimeout(resolve, ms);
    signal?.addEventListener("abort", () => {
      clearTimeout(t);
      reject(signal.reason);
    });
  });
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `setInterval` does not wait for async work — callbacks can overlap; use recursive `setTimeout`.
* Timer ids are numbers in browsers, objects in Node — don’t assume type.
* Forgetting to clear timers on unmount leaks and causes “setState on unmounted” bugs.
* `rAF` pauses in background tabs; don’t use it for critical non-visual deadlines.
* String eval form `setTimeout("code", 0)` is obsolete and unsafe.

## 🔗 Related [#-related]

* [event\_loop.md](/docs/javascript/event-loop) — task queues
* [abort\_controller.md](/docs/javascript/abort-controller) — cancel async waits
* [performance.md](/docs/javascript/performance) — measuring delays
* [promise.md](/docs/javascript/promise) — sleep helpers
* [web\_workers.md](/docs/javascript/web-workers) — timers in workers


---

# Type Coercion (/docs/javascript/type-coercion)



# Type Coercion [#type-coercion]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Coercion converts values between types implicitly (`==`, `+`, `if`) or explicitly (`Number`, `String`, `Boolean`, `BigInt`). Prefer explicit conversions. Know `ToPrimitive`, string concatenation vs addition, and truthiness to debug surprising results.

## 🔧 Core concepts [#-core-concepts]

* **Explicit**: `Number(x)`, `String(x)`, `Boolean(x)`, `BigInt(x)`, `parseInt` / `parseFloat`.
* **Implicit**: `+x` (number), `x + ""` (string), `!!x` (boolean), `==` rules.
* **`+`**: if either side is string, concatenate; else numeric add.
* **`ToPrimitive`**: prefers `valueOf` then `toString` (hint-dependent).
* **Truthy/falsy**: see conditionals — not the same as `Boolean` edge cases for objects.

```js
Number("42"); // 42
String(42); // "42"
Boolean(0); // false
"3" + 1; // "31"
+"3" + 1; // 4
```

## 💡 Examples [#-examples]

```js
// Numeric
Number(""); // 0
Number("  12 "); // 12
Number("12a"); // NaN
parseInt("12a", 10); // 12
parseInt("08", 10); // 8 — always pass radix

// Boolean
Boolean([]); // true
Boolean({}); // true
Boolean(""); // false

// == coercion highlights (avoid)
false == 0; // true
"" == 0; // true
null == undefined; // true
null == 0; // false

// Objects
[] + []; // ""
[] + {}; // "[object Object]"
{} + []; // depends on ASI / context — avoid

// valueOf / toString
const money = {
  valueOf() {
    return 100;
  },
};
money + 1; // 101

// Explicit helpers
const toInt = (v) => {
  const n = Number.parseInt(String(v), 10);
  return Number.isFinite(n) ? n : null;
};
```

```js
// Template always stringifies
`${[1, 2]}`; // "1,2"
`${{ a: 1 }}`; // "[object Object]"
```

## ⚠️ Pitfalls [#️-pitfalls]

* `parseInt` without radix and hex/`0`-prefix history — always pass `10`.
* `Number(null)` is `0` but `Number(undefined)` is `NaN`.
* Arrays coerce to strings via `join` — `==` comparisons get weird.
* `BigInt` does not coerce with `Number` in arithmetic — convert deliberately.
* Relying on `==` “convenience” creates subtle bugs — use `===` + explicit casts.

## 🔗 Related [#-related]

* [equality.md](/docs/javascript/equality) — === vs ==
* [boolean.md](/docs/javascript/boolean) — ToBoolean
* [number.md](/docs/javascript/number) — Number quirks
* [bigint.md](/docs/javascript/bigint) — BigInt conversion
* [strings.md](/docs/javascript/strings) — String conversion


---

# Typed Arrays (/docs/javascript/typed-arrays)



# Typed Arrays [#typed-arrays]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Typed arrays are array-like views over binary `ArrayBuffer` (and `SharedArrayBuffer`) memory. Use them for files, WebGL, WebAudio, WASM, network protocols, and precise integer/float layouts. They fix element types and sizes — no holes, no mixed types.

## 🔧 Core concepts [#-core-concepts]

| Type                                             | Bytes | Description     |
| ------------------------------------------------ | ----- | --------------- |
| `Int8Array` / `Uint8Array` / `Uint8ClampedArray` | 1     | 8-bit           |
| `Int16Array` / `Uint16Array`                     | 2     | 16-bit          |
| `Int32Array` / `Uint32Array`                     | 4     | 32-bit          |
| `Float32Array` / `Float64Array`                  | 4 / 8 | IEEE floats     |
| `BigInt64Array` / `BigUint64Array`               | 8     | BigInt elements |

* **`ArrayBuffer`**: raw bytes; **view** interprets them.
* **`DataView`**: explicit endianness for mixed layouts.
* **`buffer` / `byteOffset` / `byteLength`**: view window into buffer.
* **Endianness**: typed arrays use platform endianness; DataView lets you choose.

```js
const buf = new ArrayBuffer(8);
const view = new Uint32Array(buf);
view[0] = 0xffffffff;
```

## 💡 Examples [#-examples]

```js
// From length / from array
const a = new Uint8Array(4);
const b = new Uint8Array([1, 2, 3, 4]);
const c = new Uint8Array(b); // copy

// Shared buffer, two views
const buffer = new ArrayBuffer(16);
const u8 = new Uint8Array(buffer);
const f32 = new Float32Array(buffer);
f32[0] = 1.5;
u8.slice(0, 4); // bytes of that float

// Subarray (view) vs slice (copy)
const mid = u8.subarray(2, 6); // shares buffer
const copy = u8.slice(2, 6); // new buffer

// DataView for protocols
const dv = new DataView(buffer);
dv.setUint16(0, 0x1234, false); // big-endian
dv.getUint16(0, false);

// Bytes from string
const enc = new TextEncoder().encode("hi");
const dec = new TextDecoder().decode(enc);

// Fetch as bytes
const res = await fetch("/file.bin");
const bytes = new Uint8Array(await res.arrayBuffer());
```

```js
// Clamped for canvas ImageData
const clamped = new Uint8ClampedArray([300, -1, 128]);
// [255, 0, 128]
```

## ⚠️ Pitfalls [#️-pitfalls]

* Out-of-range assigns wrap (or clamp for `Uint8ClampedArray`) — no throw.
* `TypedArray` is not a real `Array` — no `push`/`pop`; some methods differ.
* Endian bugs when exchanging binary across architectures — prefer DataView for wire formats.
* Detached buffers (after `postMessage` transfer / WASM) throw on access.
* Align `byteOffset` to element size for multi-byte typed arrays.

## 🔗 Related [#-related]

* [bigint.md](/docs/javascript/bigint) — BigInt64Array
* [encode.md](/docs/javascript/encode) — TextEncoder
* [web\_workers.md](/docs/javascript/web-workers) — transferable buffers
* [fetch.md](/docs/javascript/fetch) — arrayBuffer bodies
* [DOM/… canvas](/docs/javascript/../html/canvas) — ImageData buffers


---

# typeof Basics (/docs/javascript/typeof-basics)



# typeof Basics [#typeof-basics]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`typeof` is an operator that returns a string describing a value’s type tag. It is useful for quick checks while learning, with a few famous quirks to memorize.

## 🔧 Core concepts [#-core-concepts]

| Expression                    | Typical result            |
| ----------------------------- | ------------------------- |
| `typeof "hi"`                 | `"string"`                |
| `typeof 42`                   | `"number"`                |
| `typeof 42n`                  | `"bigint"`                |
| `typeof true`                 | `"boolean"`               |
| `typeof undefined`            | `"undefined"`             |
| `typeof Symbol()`             | `"symbol"`                |
| `typeof \{\}` / `[]` / `null` | `"object"` (see pitfalls) |
| `typeof function () \{\}`     | `"function"`              |

`typeof` never throws on an undeclared variable in older patterns like `typeof x` — it yields `"undefined"`. Prefer declared variables anyway.

## 💡 Examples [#-examples]

**Primitives:**

```js
console.log(typeof "hello"); // string
console.log(typeof 3.14);    // number
console.log(typeof true);    // boolean
console.log(typeof undefined); // undefined
```

**Objects and functions:**

```js
console.log(typeof { a: 1 });     // object
console.log(typeof [1, 2]);       // object
console.log(typeof null);         // object  ← historical bug
console.log(typeof (() => 1));    // function
```

**Guarding before use:**

```js
function double(n) {
  if (typeof n !== "number" || Number.isNaN(n)) {
    throw new TypeError("n must be a number");
  }
  return n * 2;
}

console.log(double(21));
```

**Optional value check:**

```js
let title;
console.log(typeof title); // undefined
title = "Docs";
console.log(typeof title); // string
```

## ⚠️ Pitfalls [#️-pitfalls]

* `typeof null === "object"` — check null with `value === null`.
* Arrays are `"object"` — use `Array.isArray(x)`.
* `typeof NaN` is `"number"`.
* For class instances, prefer `instanceof` or brand checks over `typeof`.

## 🔗 Related [#-related]

* [variables\_let\_const.md](/docs/javascript/variables-let-const)
* [null\_undefined.md](/docs/javascript/null-undefined)
* [hello\_world.md](/docs/javascript/hello-world)
* [equality.md](/docs/javascript/equality)


---

# URL & URLSearchParams (/docs/javascript/url)



# URL & URLSearchParams [#url--urlsearchparams]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

The `URL` API parses and builds absolute URLs safely. `URLSearchParams` reads and writes the query string without manual encoding mistakes. Prefer these over string concatenation.

## 🔧 Core concepts [#-core-concepts]

* **`new URL(url, base?)`**: parse; throws `TypeError` on invalid input.
* **Parts**: `protocol`, `username`, `password`, `host`, `hostname`, `port`, `pathname`, `search`, `hash`, `href`, `origin`.
* **`searchParams`**: live `URLSearchParams` view of the query.
* **Params API**: `get`, `getAll`, `set`, `append`, `delete`, `has`, `sort`, iterate.
* **Relative resolve**: `new URL("/x", "https://example.com/a/")`.

```js
const u = new URL("https://example.com:443/path?q=1#top");
u.hostname; // example.com
u.searchParams.get("q"); // "1"
```

## 💡 Examples [#-examples]

```js
// Build safely
const url = new URL("https://api.example.com/v1/search");
url.searchParams.set("q", "café & tea");
url.searchParams.set("page", "2");
console.log(url.href);

// Resolve relative
const abs = new URL("../img/a.png", "https://cdn.example.com/assets/css/");
// https://cdn.example.com/assets/img/a.png

// Read from location (browser)
const page = new URL(location.href);
const tab = page.searchParams.get("tab") ?? "home";

// From form-urlencoded body
const params = new URLSearchParams("a=1&a=2&b=3");
params.getAll("a"); // ["1","2"]

// Iterate
for (const [k, v] of url.searchParams) {
  console.log(k, v);
}

// Update path
url.pathname = "/v2/search";

// canParse (modern)
URL.canParse?.("https://ok.test"); // true
```

```js
await fetch(url, { method: "GET" });

// POST as form body
await fetch("/login", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({ user: "ada", remember: "1" }),
});
```

## ⚠️ Pitfalls [#️-pitfalls]

* `new URL("/path")` without base throws in many environments — provide base or use absolute href.
* `searchParams.set` replaces all values for a key; use `append` for multi-value keys.
* Mutating `url.search` and `searchParams` stay in sync — pick one style.
* `pathname` encoding differs from full component encoding — use `encodeURIComponent` for segments you insert.
* `origin` is read-only; change via protocol/host/port pieces.

## 🔗 Related [#-related]

* [encode.md](/docs/javascript/encode) — encodeURIComponent
* [fetch.md](/docs/javascript/fetch) — requesting URLs
* [strings.md](/docs/javascript/strings) — string building
* [api.md](/docs/javascript/api) — related web APIs
* [DOM/window.md](/docs/javascript/dom/window) — location
* [DOM/navigation.md](/docs/javascript/dom/navigation) — history / location


---

# Node URL helpers (/docs/javascript/url-node)



# Node URL helpers [#node-url-helpers]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Node.js `node:url` complements the WHATWG `URL&#x60; API with filesystem bridges: &#x2A;*`pathToFileURL`*&#x2A;, &#x2A;*`fileURLToPath`**, and legacy `url.parse` (avoid). Use these when converting between OS paths and `file:` URLs — especially in ESM (`import.meta.url`).

```js
import { pathToFileURL, fileURLToPath } from "node:url";
```

## 🔧 Core concepts [#-core-concepts]

* **`URL`**: standard absolute URL class (also global in Node) — `href`, `pathname`, `searchParams`, etc.
* **`pathToFileURL(path)`**: absolute filesystem path → `URL` with `file:` protocol.
* **`fileURLToPath(url)`**: `file:` URL / string → absolute OS path (handles Windows quirks).
* **`import.meta.url`**: ESM module’s own `file:` URL.
* **Legacy**: `url.parse` / `url.format` are legacy; prefer WHATWG `URL`.

## 💡 Examples [#-examples]

```js
import path from "node:path";
import { pathToFileURL, fileURLToPath } from "node:url";

// ESM __filename / __dirname
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const fileUrl = pathToFileURL(path.join(__dirname, "data.json"));
console.log(fileUrl.href); // file:///…

const back = fileURLToPath(fileUrl);
console.log(back); // absolute path

// Dynamic import from path
const modUrl = pathToFileURL(path.join(__dirname, "plugin.js")).href;
const plugin = await import(modUrl);

// WHATWG URL (same as browsers)
const u = new URL("https://example.com/a?x=1#h");
u.searchParams.get("x"); // '1'
u.pathname = "/b";
console.log(u.toString());
```

```js
// Resolve relative to current module
const asset = new URL("./assets/logo.png", import.meta.url);
const assetPath = fileURLToPath(asset);
```

## ⚠️ Pitfalls [#️-pitfalls]

* `fileURLToPath` only accepts `file:` URLs — http(s) throws.
* On Windows, paths and `file:` URLs differ (`C:\` vs `file:///C:/`); always convert with these helpers.
* `URL.pathname` is percent-encoded; do not treat it as a raw filesystem path — use `fileURLToPath`.
* Legacy `url.parse` is mutable/quirky and marked legacy in docs.
* Relative path strings are not valid `URL` bases without a base argument.

## 🔗 Related [#-related]

* [URL](/docs/javascript/url) — WHATWG `URL` / `URLSearchParams`
* [Path](/docs/javascript/path) — `join`, `dirname`, `resolve`
* [ESM import/export](/docs/javascript/import-export) — `import.meta.url`
* [CommonJS modules](/docs/javascript/modules-commonjs) — `__dirname` without URL helpers
* [fetch](/docs/javascript/fetch) — requesting http(s) URLs
* [fs](/docs/javascript/fs) — open paths from `fileURLToPath`


---

# util (/docs/javascript/util)



# util [#util]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Node.js `node:util` offers helpers for promisifying callback APIs, debugging inspection, type checks, and text formatting. Small but frequently used when bridging older Node APIs to async/await.

```js
import util from "node:util";
```

## 🔧 Core concepts [#-core-concepts]

* **`promisify(fn)`**: wrap `(…args, (err, result) => …)` into a function returning a Promise.
* **`callbackify(fn)`**: opposite direction — Promise function → error-first callback.
* **`inspect(obj, options?)`**: rich string representation for logging (depth, colors, getters).
* **`util.types`**: precise type predicates (`isPromise`, `isDate`, `isRegExp`, `isUint8Array`, …).
* **`format` / `styleText`**: printf-like formatting; styled terminal text (Node 20+ for `styleText`).
* **`deprecate(fn, msg)`**: wrap APIs to emit deprecation warnings once.

## 💡 Examples [#-examples]

```js
import util from "node:util";
import { readFile } from "node:fs";
import { execFile } from "node:child_process";

const readFileP = util.promisify(readFile);
const text = await readFileP("a.txt", "utf8");

const execFileP = util.promisify(execFile);
const { stdout } = await execFileP("node", ["-v"]);

console.log(util.inspect({ a: 1, nest: { b: [1, 2] } }, { depth: 3, colors: true }));

const { types } = util;
types.isPromise(Promise.resolve(1)); // true
types.isDate(new Date()); // true
types.isRegExp(/x/); // true

util.format("%s: %d", "count", 3); // 'count: 3'

const oldApi = util.deprecate(function legacy() {}, "legacy() is deprecated");
oldApi();
```

```js
// Custom inspect
const box = {
  value: 42,
  [util.inspect.custom](depth, opts) {
    return `Box(${this.value})`;
  },
};
console.log(util.inspect(box)); // Box(42)
```

## ⚠️ Pitfalls [#️-pitfalls]

* `promisify` expects error-first callbacks; nonstandard APIs need a custom promisify symbol or manual wrapper.
* `inspect` default depth can hide nested data — raise `depth` or use `depth: null` carefully (huge output).
* `typeof` is weaker than `util.types` for built-ins (e.g. promises, typed arrays).
* Do not use `inspect` output as a serialization format — use JSON or a real serializer.
* Some APIs already return Promises (`fs/promises`) — no need to promisify.

## 🔗 Related [#-related]

* [Async](/docs/javascript/async) — async/await with promisified APIs
* [Promise](/docs/javascript/promise) — Promise basics
* [fs](/docs/javascript/fs) — prefer `fs/promises` over promisify
* [child\_process](/docs/javascript/child-process) — promisify `execFile`
* [typeof basics](/docs/javascript/typeof-basics) — `typeof` vs precise checks
* [console](/docs/javascript/console) — logging alternatives


---

# Variables: let and const (/docs/javascript/variables-let-const)



# Variables: let and const [#variables-let-and-const]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Modern JavaScript declares variables with `let` and `const`. Avoid `var` in new code. `const` prevents reassignment of the binding; `let` allows reassignment. Both are block-scoped.

## 🔧 Core concepts [#-core-concepts]

| Keyword | Reassign? | Scope        | Typical use        |
| ------- | --------- | ------------ | ------------------ |
| `const` | No        | Block `\{\}` | Default choice     |
| `let`   | Yes       | Block `\{\}` | Values that change |
| `var`   | Yes       | Function     | Legacy only        |

`const` objects/arrays can still have their *contents* mutated — the binding cannot point to a new object.

## 💡 Examples [#-examples]

**Basic declarations:**

```js
const name = "Sam";
let score = 0;

score = score + 10;
// name = "Alex"; // TypeError
console.log(name, score);
```

**Block scope:**

```js
let x = 1;
{
  let x = 2;
  console.log(x); // 2
}
console.log(x); // 1
```

**const with objects:**

```js
const user = { id: 1, role: "guest" };
user.role = "admin"; // OK — mutating property
// user = {};       // TypeError — rebinding

const nums = [1, 2];
nums.push(3); // OK
console.log(user, nums);
```

**Temporal dead zone (use before declare):**

```js
// console.log(a); // ReferenceError
let a = 5;
console.log(a);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Prefer `const` until you know a value must change.
* `const` ≠ deeply immutable.
* Redeclaring the same `let`/`const` in one scope is a SyntaxError.
* Forgetting `let`/`const` creates an accidental global in non-strict sloppy mode.

## 🔗 Related [#-related]

* [hello\_world.md](/docs/javascript/hello-world)
* [typeof\_basics.md](/docs/javascript/typeof-basics)
* [null\_undefined.md](/docs/javascript/null-undefined)
* [template\_basics.md](/docs/javascript/template-basics)


---

# WeakMap & WeakSet (/docs/javascript/weakmap-weakset)



# WeakMap & WeakSet [#weakmap--weakset]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`WeakMap` and `WeakSet` hold **weak** references to object keys/values so entries can be garbage-collected when nothing else references the key. They are not iterable and have no `.size` — designed for private metadata, caching, and DOM-associated state without leaks.

## 🔧 Core concepts [#-core-concepts]

* **WeakMap**: keys must be objects (or non-registered symbols in modern engines); values any.
* **API**: `get`, `set`, `has`, `delete` — no iteration.
* **WeakSet**: objects only; `add`, `has`, `delete`.
* **GC**: when key is unreachable, entry may disappear.
* **vs Map/Set**: strong refs keep keys alive forever if the collection lives.

```js
const wm = new WeakMap();
const el = document.createElement("div");
wm.set(el, { clicks: 0 });
wm.get(el).clicks++;
```

## 💡 Examples [#-examples]

```js
// Private data per instance (pre-#fields pattern)
const _balance = new WeakMap();
class Account {
  constructor(amount) {
    _balance.set(this, amount);
  }
  deposit(n) {
    _balance.set(this, _balance.get(this) + n);
  }
  get balance() {
    return _balance.get(this);
  }
}

// DOM metadata without expando properties
const state = new WeakMap();
function track(el) {
  if (!state.has(el)) state.set(el, { seen: 0 });
  state.get(el).seen++;
}

// Visited set for graph walk (objects)
const seen = new WeakSet();
function walk(node) {
  if (seen.has(node)) return;
  seen.add(node);
  for (const child of node.children ?? []) walk(child);
}

// Cache expensive computation keyed by object
const cache = new WeakMap();
function meta(obj) {
  if (cache.has(obj)) return cache.get(obj);
  const value = compute(obj);
  cache.set(obj, value);
  return value;
}
```

```js
// WeakRef / FinalizationRegistry (related, stronger control)
const ref = new WeakRef(obj);
ref.deref(); // obj or undefined if collected
```

## ⚠️ Pitfalls [#️-pitfalls]

* Primitives cannot be WeakMap keys (except allowed symbols) — box or use Map.
* Not enumerable: you cannot list keys for debugging easily.
* Do not rely on *when* GC runs — only that entries *may* go away.
* WeakMap values stay alive while the key is reachable — value holding key = leak cycle still collectable if only weakly held… avoid mutual strong cycles via other roots.
* `WeakSet` has no get — membership only.

## 🔗 Related [#-related]

* [map.md](/docs/javascript/map) — strong Map
* [set.md](/docs/javascript/set) — strong Set
* [oop.md](/docs/javascript/oop) — `#private` fields
* [DOM/storage.md](/docs/javascript/dom/storage) — not for persistence
* [objects.md](/docs/javascript/objects) — object identity as keys


---

# Web Workers (/docs/javascript/web-workers)



# Web Workers [#web-workers]

*JavaScript · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Web Workers run scripts off the main thread so heavy CPU work does not block UI. Dedicated workers are owned by one page; shared workers can be used by multiple; service workers intercept network (separate topic). Communicate via `postMessage` and structured clone / transferables.

## 🔧 Core concepts [#-core-concepts]

* **Create**: `new Worker(new URL("./worker.js", import.meta.url), \{ type: "module" \})`.
* **Messages**: `worker.postMessage(data, transfer?)` / `onmessage` / `message` event.
* **Terminate**: `worker.terminate()`; inside worker `self.close()`.
* **No DOM**: no `document`/`window` UI APIs; have `fetch`, timers, IndexedDB, WebAssembly, etc.
* **Transfer**: `ArrayBuffer`, `MessagePort`, some streams — zero-copy move.
* **Errors**: `worker.onerror`, `unhandledrejection` in module workers.

```js
const worker = new Worker(new URL("./heavy.js", import.meta.url), {
  type: "module",
});
worker.postMessage({ op: "sum", values: [1, 2, 3] });
worker.onmessage = (e) => console.log(e.data);
```

## 💡 Examples [#-examples]

```js
// main.js
const w = new Worker(new URL("./worker.js", import.meta.url), { type: "module" });
w.postMessage({ n: 40 });
w.addEventListener("message", (e) => {
  console.log("fib", e.data);
  w.terminate();
});

// worker.js
self.onmessage = (e) => {
  const { n } = e.data;
  self.postMessage(fib(n));
};
function fib(n) {
  return n < 2 ? n : fib(n - 1) + fib(n - 2);
}

// Transfer large buffer
const bytes = new Uint8Array(1_000_000);
worker.postMessage(bytes, [bytes.buffer]); // bytes.buffer detached

// MessageChannel for ports
const { port1, port2 } = new MessageChannel();
worker.postMessage({ port: port2 }, [port2]);
port1.onmessage = (e) => console.log(e.data);
```

```js
// Pool sketch
class Pool {
  constructor(size, url) {
    this.idle = Array.from(
      { length: size },
      () => new Worker(url, { type: "module" }),
    );
  }
  run(data) {
    const w = this.idle.pop();
    return new Promise((resolve, reject) => {
      w.onmessage = (e) => {
        this.idle.push(w);
        resolve(e.data);
      };
      w.onerror = reject;
      w.postMessage(data);
    });
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Classic workers need separate classic scripts; prefer `\{ type: "module" \}` + `import.meta.url`.
* Cloning large object graphs is expensive — transfer buffers or use `SharedArrayBuffer` (COOP/COEP).
* Workers don’t share memory with the page (except SAB) — no shared closures.
* Forgetting `terminate()` leaks threads.
* DOM / most Web APIs involving UI are unavailable — design data in/out carefully.

## 🔗 Related [#-related]

* [structured\_clone.md](/docs/javascript/structured-clone) — clone/transfer
* [typed\_arrays.md](/docs/javascript/typed-arrays) — binary payloads
* [event\_loop.md](/docs/javascript/event-loop) — main thread vs worker
* [abort\_controller.md](/docs/javascript/abort-controller) — cancel work
* [performance.md](/docs/javascript/performance) — measuring offload wins


---

# while / do...while (/docs/javascript/while)



# while / do...while [#while--dowhile]

*JavaScript · Reference cheat sheet*

## 📋 Overview [#-overview]

`while` repeats while a condition is truthy. `do...while` runs the body at least once. Use when the end condition is not a simple index range — and always ensure progress toward termination.

## 🔧 Core concepts [#-core-concepts]

* **`while (cond) \{ body \}`**: test first.
* **`do \{ body \} while (cond)`**: test after.
* **Control**: `break`, `continue`, labels.
* **Condition**: coerced with ToBoolean.
* **vs `for`**: `for` is clearer for known bounds; `while` for sentinel / stream / backoff loops.

```js
let n = 3;
while (n > 0) {
  console.log(n);
  n -= 1;
}
```

## 💡 Examples [#-examples]

```js
// Read until sentinel
let line;
while ((line = readLine()) !== null) {
  process(line);
}

// do...while menu
let choice;
do {
  choice = prompt("1) go  0) quit");
} while (choice !== "0" && choice !== null);

// Exponential backoff
async function retry(fn, attempts = 5) {
  let i = 0;
  let delay = 100;
  while (true) {
    try {
      return await fn();
    } catch (err) {
      if (++i >= attempts) throw err;
      await new Promise((r) => setTimeout(r, delay));
      delay *= 2;
    }
  }
}

// Linked list walk
let node = head;
while (node) {
  visit(node);
  node = node.next;
}

// continue / break
let i = 0;
while (i < 10) {
  i += 1;
  if (i % 2 === 0) continue;
  if (i > 7) break;
  console.log(i);
}
```

```js
// Poll with abort
async function waitFor(pred, signal, ms = 50) {
  while (!signal.aborted) {
    if (await pred()) return true;
    await new Promise((r) => setTimeout(r, ms));
  }
  return false;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Infinite loops from missing updates or always-true conditions — guard with counters/timeouts.
* `while (await fetch...)` without delay can hammer servers.
* Assignments in conditions (`while (x = next())`) need parentheses and careful null checks.
* `continue` in `do...while` still re-checks the condition — know your flow.
* Prefer `for...of` when iterating collections.

## 🔗 Related [#-related]

* [iteration.md](/docs/javascript/iteration) — loop overview
* [for\_of.md](/docs/javascript/for-of) — for...of
* [boolean.md](/docs/javascript/boolean) — truthiness
* [async.md](/docs/javascript/async) — async loops
* [promise.md](/docs/javascript/promise) — delays / retry
* [iterator.md](/docs/javascript/iterator) — generator loops

