Files
ivangdavila_web/javascript.md

36 lines
1.9 KiB
Markdown

# JavaScript Patterns and Traps
## Type Coercion
- **`==` vs `===`** — Always use `===`; `"0" == false` is true, `"0" === false` is false
- **`typeof null`** — Returns `"object"` (bug from JS v1); check with `=== null`
- **`NaN !== NaN`** — Use `Number.isNaN()` not `=== NaN`
- **Array in boolean context** — Empty array `[]` is truthy; check `.length` for emptiness
## Async
- **`forEach` doesn't await** — Use `for...of` loop or `Promise.all(arr.map(async...))` for parallel
- **Unhandled rejection** — Always `.catch()` or wrap in try/catch; uncaught rejections crash Node
- **`async` function returns Promise** — Even if you return a value, caller gets a Promise
- **Race conditions** — Multiple `setState` calls can overwrite; use functional updates or refs
## DOM
- **`querySelector` returns null** — Check before accessing properties; `document.querySelector('.x').classList` crashes if `.x` missing
- **Event delegation** — Add listener to parent, check `e.target`; better than listeners on each child
- **`innerHTML` security** — Never insert user content with `innerHTML`; use `textContent` or sanitize
- **Live vs static NodeLists** — `getElementsByClassName` is live (updates); `querySelectorAll` is static
## Objects/Arrays
- **Shallow copy** — `{...obj}` and `[...arr]` are shallow; nested objects share references
- **Array holes** — `Array(5)` creates holes; `.map()` skips them; use `Array(5).fill()` instead
- **`delete` on array** — Creates hole, doesn't shift; use `.splice()` to remove elements
- **Object key order** — Guaranteed insertion order for string keys; numeric keys sort ascending
## Functions
- **`this` in arrow functions** — Lexically bound; can't be changed with `.bind()`, `.call()`, `.apply()`
- **Default parameters evaluate** — `fn(x = Date.now())` evaluates on each call, not definition
- **Rest parameters must be last** — `fn(...rest, other)` is syntax error