Skip to main content

javascript

Write and review JavaScript: declarations, equality and coercion, functions, objects, iteration, classes, async and promise semantics, ES modules, regular expressions, JSDoc typing, and the ECMAScript features a project's engine baseline permits.

Quellinformationen

Repository
xobotyi/cc-foundry
Letzte Quellaktivität
13. Oktober 2026 um 09:31
Erkannte Sprache von SKILL.md
Englisch
Sterne
22
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
18 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
javascript
description
Write and review JavaScript: declarations, equality and coercion, functions, objects, iteration, classes, async and promise semantics, ES modules, regular expressions, JSDoc typing, and the ECMAScript features a project's engine baseline permits.
when_to_use
Invoke whenever JavaScript is touched at all — writing, reviewing, refactoring, debugging, or exploring a `.js`, `.mjs`, `.cjs`, or `.jsx` file, or raising a project's engine baseline. Also invoke on the symptoms: a comparison succeeds that should not, a promise rejects with nobody listening, `sort` returns the wrong order, an import reads `undefined` at module top level, a regex matches once and then fails, a class field is `undefined` inside a constructor, or a feature that runs in Node fails in a browser. Covers the language and its built-in globals; types belong to the typescript skill, runtime APIs to nodejs and bun, test authoring to vitest, and language-agnostic workflow to the coding skill.
compatibility
Uses Claude Code frontmatter beyond the Agent Skills spec (when_to_use)
**JavaScript fails by continuing.** A mismatched type is coerced, a missing property is `undefined`, a rejected promise nobody watched is a warning. None of it reports itself, so the discipline is to make a failure loud at the earliest point it can be seen. Three biases decide most calls: - **Prefer the construct that refuses over the one that converts** — `===` over `==`, `??` over `||`, `Number(s)` over `parseInt(s)`, a thrown error over a silent `undefined`. - **The declared engine baseline decides what may be written**, not the ECMAScript edition a feature belongs to. - **Reach for the built-in globals first.** A dependency earns its place by doing what `Intl`, `URL`, `structuredClone`, `AbortController`, and the iterator helpers do not. ## Language Edition Read the project's engine baseline before writing code: `engines` in `package.json`, `browserslist`, `target` and `lib` in `tsconfig.json` or `jsconfig.json`, `.nvmrc`, and the CI matrix. Where a transpiler stands between source and runtime, its target governs the output and the source may run ahead; where none does, the engine baseline's oldest engine governs the source. **An edition number is not an availability claim.** Engines ship features years before ratification and lag on others, and the gap runs both ways inside a single edition: `Array.fromAsync` and `Math.sumPrecise` are both ES2026, yet the first shipped in Chrome 121 and reached Baseline widely available on 2026-07-25, while the second reached Baseline newly available on 2026-04-10 and is absent from Node.js 26. Check the feature, never the edition. Floor edition per feature this skill's rules reference. Anything from ES2019 or earlier is available in every engine a project can realistically target. - **ES2020** — `?.`, `??`, `globalThis`, `BigInt`, `Promise.allSettled`, `String.prototype.matchAll`, dynamic `import()`, `import.meta`, specified `for...in` order - **ES2021** — `??=`, `||=`, `&&=`, `String.prototype.replaceAll`, `Promise.any`, `AggregateError`, numeric separators - **ES2022** — class fields, `#private` fields and methods, `#x in obj`, `static {}` blocks, top-level `await`, `Object.hasOwn`, `.at()`, `Error` `cause`, RegExp `d` flag - **ES2023** — `toSorted`, `toReversed`, `toSpliced`, `with`, `findLast`, `findLastIndex` - **ES2024** — `Object.groupBy`, `Map.groupBy`, `Promise.withResolvers`, RegExp `v` flag, `String.prototype.isWellFormed` - **ES2025** — iterator helpers, `Set` methods (`union`, `intersection`, `difference`, …), `Promise.try`, `RegExp.escape`, RegExp modifiers `(?i:)`, duplicate named capture groups, import attributes, JSON modules - **ES2026** — `Map.prototype.getOrInsert` and `getOrInsertComputed`, `Iterator.concat`, `Array.fromAsync`, `Error.isError`, `Math.sumPrecise`, `Uint8Array` base64 and hex, `JSON.rawJSON` - **Stage 4, unratified** — `using` and `await using` with `Symbol.dispose` and `DisposableStack`; `Temporal`; `Iterator.zip`. No Safari 26.x release implements any of them, so none is safe for an engine baseline that includes Safari 26. `using` requires Chrome 134, Firefox 141, or Node.js 24; `Temporal` requires Chrome 144, Firefox 139, or Node.js 26. `Atomics.pause` is the exception, reaching Chrome 133, Firefox 137, and Safari 18.4. - **Not shippable** — decorators are Stage 2.7 and no engine implements them. A project using them runs TypeScript or Babel, and TypeScript's `experimentalDecorators` is the older, incompatible design. Read [`${CLAUDE_SKILL_DIR}/references/versions/es20NN.md`] — one file per ratified edition, `es2020.md` through `es2026.md`, plus [`${CLAUDE_SKILL_DIR}/references/versions/stage4-queue.md`] for the unratified set — when writing against a feature near the engine baseline, and whenever raising it. Each carries what its edition added, what behavior it changed, and the traps it introduced. ## Naming - **One word per concept across the codebase.** `getUser` everywhere, never `getUser` beside `fetchUserInfo` and `loadCustomerRecord`. - **`url`, `id`, `err`, `ctx`, `req`, `res`, `db`, `fn` are the accepted abbreviations.** Spell out everything else in code. A signature written to describe an API rather than to run — `Object.groupBy(items, cb)` — takes the placeholder name the documentation uses. - **No redundant context**: `car.make`, never `car.carMake`. - **Name a value or a type for its role, never its structure.** `UserShape`, `UserObject`, `UserData`, and `userArray` restate what the declaration already shows; `User`, `users`, `UserPatch`, and `UserRow` say what the value is for. - **File names are kebab-case**: `user-service.js`. Match the surrounding directory when it already differs. - **A single-letter name is legal in a scope of one or two lines** — a loop index, a comparator parameter — and nowhere else. ## Declarations and Scope - **Never `var`.** It is function-scoped and hoists to `undefined`, which is why it survives only in code that predates block scoping. - **`const` freezes the binding, not the value.** A `const` object is still mutable. - **One declaration per statement.** `const a = 1, b = 2` breaks under a debugger and under `git blame`. - **Declare at first use, not at the top of the function.** The distance between declaration and use is the variable's real scope. - **A `let` that is assigned exactly once in every branch wants a ternary or a helper function returning `const`.** ## Equality and Coercion - **`===` and `!==` always, with one exception:** `value == null` tests `null` and `undefined` together, and the strict alternative is longer without being clearer. - **`??` for defaults, `||` only when `0`, `""`, and `false` genuinely mean "absent".** Every configuration default is `??`. - **`?.` where the absence is expected, never to silence a bug.** Data that must be present throws at the access rather than surfacing as `undefined` three frames later. `obj?.method()` still throws when `method` is missing; write `obj?.method?.()` when both are optional. - **`??` cannot be mixed with `||` or `&&` without parentheses** — it is a `SyntaxError`. - **The falsy set is `false`, `0`, `-0`, `0n`, `""`, `null`, `undefined`, `NaN`.** `[]`, `{}`, and `"0"` are truthy. - **`Number.isNaN`, never the global `isNaN`**, which coerces first: `isNaN("abc")` is `true`. - **`Number(s)` over `parseInt(s)` for a whole-string conversion.** `parseInt` stops at the first invalid character, so `parseInt("1e3")` is `1`. Never pass `parseInt` as a bare callback — `map` supplies the index as the radix, and `["1","7","11"].map(parseInt)` is `[1, NaN, 3]`. - **Never compute money in a double.** `(1.005).toFixed(2)` is `"1.00"`. Hold integer minor units, and format with `Intl.NumberFormat`. - **`Object.is` only for `NaN` and `-0`.** Everywhere else it is `===` with extra ceremony. Read [`${CLAUDE_SKILL_DIR}/references/conventions/coercion.md`] when a comparison behaves inconsistently between two built-ins, when a number loses precision, or when a copy shares state it should not — it carries the four equality algorithms and which built-in uses each, the `-0` sources, BigInt mixing rules, property-order rules, and the prototype-pollution boundary. ## Functions - **Arrow functions for callbacks, `function` declarations for named module-level functions.** A `function` declaration hoists, which lets helpers sit below the code that reads them. - **Never an arrow function as an object method or on a prototype.** It has no `this` of its own. - **Guard clauses first, happy path unindented.** A function whose body is one `if` wrapping everything wants an early return. - **Destructure the parameter object at three or more parameters.** Positional arguments past two are unreadable at the call site and impossible to extend. - **Default parameters over `||` inside the body.** They are evaluated left to right and may reference earlier parameters. - **Rest parameters, never `arguments`** — `arguments` is array-like, absent in arrow functions, and defeats optimization. - **Return an object when returning several values.** A tuple binds callers to positional order. - **A closure keeps the whole scope alive, not the values it reads.** A callback that captures one field of a large object retains the object. ## Objects and Copying - **Spread over `Object.assign` for a copy**, because it does not fire setters on the target. Both are shallow and both drop the prototype. - **`structuredClone` for a deep copy of data.** It throws `DataCloneError` on functions and symbols, and discards the prototype, so a class instance clones to a plain object. - **`Object.hasOwn(obj, key)`, never `obj.hasOwnProperty(key)`** — the latter breaks on a null-prototype object. - **Dot notation for a known key, brackets only for a computed one.** - **`Object.freeze` is shallow.** Freezing a tree means freezing every level, or not claiming immutability. - **Never mutate a parameter**, except a `reduce` accumulator whose initial value the same call created. Return a new value; the caller decides whether to keep the old one. - **Never extend a built-in prototype.** It is visible to every dependency in the process. ## Arrays and Iteration - **`for...of` for side effects, array methods for transformation, `for` only when the index is used.** `forEach` cannot `break` and does not await; reach for it only when the callback is already a named function. - **Never `for...in` on an array**, and rarely on an object — it walks inherited enumerable keys. - **Always pass a comparator to `sort` for numbers.** The default is lexicographic: `[1, 5, 10, 2].sort()` is `[1, 10, 2, 5]`. The comparator must return a number; `(a, b) => a > b` returns booleans, which makes the order implementation-defined and the bug engine-dependent. - **`sort` and `reverse` mutate.** Prefer `toSorted` and `toReversed` where the engine baseline allows. - **Never `delete` an array element.** It leaves a hole and does not change `length`. Use `splice` or `filter`. - **Build a dense array with `Array.from({ length: n })` or `[...Array(n)]`.** `Array(n).map(f)` calls `f` zero times, because array methods skip holes while spread and `for...of` treat them as `undefined`. - **`Map` when keys are not strings, come from outside the program, or must keep insertion order.** Object keys are stringified, and integer-like keys reorder themselves ahead of the rest. - **`Set` for membership and deduplication** — `[...new Set(items)]`. - **Grow an accumulator in place, never by copying it.** `{ ...acc, [k]: v }`, `[...acc, x]`, `acc.concat(x)`, and `Object.assign({}, acc, x)` copy everything gathered so far on every step, so the loop is quadratic. Measured on Node 26.9.0, a spread `reduce` over 8 000 items takes 3.7 s, and assigning into the accumulator takes under 1 ms. Assign or push into an accumulator the loop created, then return it. `Object.fromEntries`, `Object.groupBy`, and `new Map(entries)` replace most of these reductions outright. - **Iterator helpers for a stream that is infinite, expensive, or larger than memory.** They are lazy and single-pass: draining a helper drains its source. - **Sort user-visible text with `Intl.Collator`.** `<` compares UTF-16 code units, so `"ä"` sorts after `"z"`. - **Count characters with `Intl.Segmenter`, not `.length`.** `.length` counts code units and `[...str]` counts code points; neither is a user-perceived character. Read [`${CLAUDE_SKILL_DIR}/references/conventions/iteration.md`] when a loop produces the wrong count, when an array method skips elements, or when a generator's cleanup does not run — it carries the full hole-behavior split, the iterator-closing rules, and the `Map`/`Set` mutation-during-iteration semantics. ## Classes - **Reach for a class when a type has invariants, several methods over shared state, or a lifecycle.** A class with one method and no state is a function. - **`#private` fields, never a leading underscore.** `#x in obj` is the only reliable same-class test; `instanceof` is forgeable and fails across realms. - **Never call an overridable method from a constructor.** The base constructor completes before any derived field initializer runs, so the method sees `undefined`. - **A method belongs on the prototype; an arrow-function field is an own property per instance.** Use the field form only where the function is detached from its receiver. - **Composition over `extends`.** Inherit only for a real "is-a" with a shared contract. - **Omit a constructor that only calls `super(...args)`.** - **Never rely on a built-in method to return your subclass.** Array methods honor `Symbol.species` and the `Set` methods do not; `structuredClone` discards the prototype either way. Read [`${CLAUDE_SKILL_DIR}/references/conventions/classes.md`] when a field reads `undefined`, when `instanceof` gives the wrong answer, or when designing a class hierarchy — it carries the full initialization order, the private-field semantics, and the prototype-pollution rules. ## Async - **Every promise is awaited or has a handler.** `send().catch(reportError)` for fire-and-forget, which is the one place a `.then` belongs. A floating promise is a failure nobody will see. - **`.map(async …)` needs a `Promise.all` around it, and `forEach(async …)` is always wrong** — `forEach` discards the returned promise and finishes before any callback body does. - **Start independent work together, await together**: `const [a, b] = await Promise.all([f(), g()])`. Two sequential awaits with no dependency between them double the latency. - **Bound a large fan-out.** `Promise.all` over ten thousand items opens ten thousand operations. - **Pick the combinator by failure mode** — `all` when every result is required, `allSettled` when every outcome must be observed, `any` for the first success, `race` only with an `AbortController`, because the losers keep running. - **`return await` inside a `try`, plain `return` outside it.** `return promise` inside a `try` returns before the promise settles, so the `catch` never fires. - **Never `return`, `break`, or `continue` out of a `finally`** — it discards a pending throw. - **`AbortController` is the cancellation protocol.** Thread `{ signal }` through; use `AbortSignal.timeout(ms)` for a deadline and `AbortSignal.any([...])` to combine. Distinguish an abort from a real failure before retrying. - **`new Promise(...)` only to wrap a callback API.** Where a resolver must escape, `Promise.withResolvers()` returns `{ promise, resolve, reject }`. - **Sequential `await` in a loop is correct when each step depends on the last** and a defect otherwise. - **`using` and `await using` release a resource on every exit path** where the engine baseline allows them; `try`/`finally` with one nested block per resource is the equivalent elsewhere.
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen