Skill: ivangdavila/javascript (version 1.0.3)

--- name: JavaScript slug: javascript version: 1.0.3 description: Write robust JavaScript with async patterns, type coercion handling, and modern ES2023+ features. --- ## When to Use User needs JavaScript expertise — from core language features to modern patterns. Agent handles async/await, closures, module systems, and ES2023+ features. ## Quick Reference | Topic | File | |-------|------| | Async patterns | `async.md` | | Type coercion rules | `coercion.md` | | Array and object methods | `collections.md` | | Modern ES features | `modern.md` | ## Equality Traps - `==` coerces: `"0" == false` is true — use `===` always - `NaN !== NaN` — use `Number.isNaN()`, not `=== NaN` - `typeof null === "object"` — check `=== null` explicitly - Objects compare by reference — `{} === {}` is false ## this Binding - Regular functions: `this` depends on call site — lost in callbacks - Arrow functions: `this` from lexical scope — use for callbacks - `setTimeout(obj.method)` loses `this` — use arrow or `.bind()` - Event handlers: `this` is element in regular function, undefined in arrow (if no outer this) ## Closure Traps - Loop variable captured by reference — `let` in loop or IIFE to capture value - `var` hoisted to function scope — creates single binding shared across iterations - Returning function from loop: all share same variable — use `let` per iteration ## Array Mutation - `sort()`, `reverse()`, `splice()` mutate original — use `toSorted()`, `toReversed()`, `toSpliced()` (ES2023) - `push()`, `pop()`, `shift()`, `unshift()` mutate — spread `[...arr, item]` for immutable - `delete arr[i]` leaves hole — use `splice(i, 1)` to remove and reindex - Spread and `Object.assign` are shallow — nested objects still reference original ## Async Pitfalls - Forgetting `await` returns Promise, not value — easy to miss without TypeScript - `forEach` doesn't await — use `for...of` for sequential async - `Promise.all` fails fast — one rejection rejects all, use `Promise.allSettled` if need all results - Unhandled rejection crashes in Node — always `.catch()` or try/catch with await ## Numbers - `0.1 + 0.2 !== 0.3` — floating point, use integer cents or `toFixed()` for display - `parseInt("08")` works now — but `parseInt("0x10")` is 16, watch prefixes - `Number("")` is 0, `Number(null)` is 0 — but `Number(undefined)` is NaN - Large integers lose precision over 2^53 — use `BigInt` for big numbers ## Iteration - `for...in` iterates keys (including inherited) — use `for...of` for values - `for...of` on objects fails — objects aren't iterable, use `Object.entries()` - `Object.keys()` skips non-enumerable — `Reflect.ownKeys()` gets all including symbols ## Implicit Coercion - `[] + []` is `""` — arrays coerce to strings - `[] + {}` is `"[object Object]"` — object toString - `{} + []` is `0` in console — `{}` parsed as block, not object - `"5" - 1` is 4, `"5" + 1` is "51" — minus coerces, plus concatenates ## Strict Mode - `"use strict"` at top of file or function — catches silent errors - Implicit globals throw in strict — `x = 5` without declaration fails - `this` is undefined in strict functions — not global object - Duplicate parameters and `with` forbidden


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)