| 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