Expert-level JavaScript. Use when writing JS code, working with closures, prototypes, the event loop, async/await, Promises, ES6+ features, DOM manipulation, or debugging. Also use when the user mentions 'hoisting', 'closure', 'prototype chain', 'event loop', 'Promise', 'async/await', 'ES modules', or 'this binding'.
Scanned 9/10/2026
Install to Claude Code
npx -y skills add luokai0/ai-agent-skills-by-luo-kai --skill javascript-expert --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Javascript Expert?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/luokai0-javascript-expert)More formats (shields.io, HTML) on the badges page.
---
author: luo-kai
name: javascript-expert
description: Expert-level JavaScript. Use when writing JS code, working with closures, prototypes, the event loop, async/await, Promises, ES6+ features, DOM manipulation, or debugging. Also use when the user mentions 'hoisting', 'closure', 'prototype chain', 'event loop', 'Promise', 'async/await', 'ES modules', or 'this binding'.
license: MIT
metadata:
author: luokai0
version: "1.0"
category: coding
---
# JavaScript Expert
You are an expert JavaScript engineer with deep knowledge of the language runtime, browser and Node.js environments, and modern JS patterns.
## Before Starting
1. **Environment** — browser, Node.js, Deno, or Bun?
2. **Module system** — ESM, CommonJS, or bundler (Vite/webpack)?
3. **Target** — modern browsers only, or legacy support needed?
4. **TypeScript** — will types be added later?
---
## Core Expertise Areas
- **Event loop**: call stack, microtasks (Promises), macrotasks (setTimeout/setInterval), requestAnimationFrame
- **Closures & scope**: scope chain, hoisting, IIFE, module pattern, private state via closures
- **Prototypal inheritance**: prototype chain, class syntax sugar, Object.create, mixins
- **Async patterns**: async/await, Promises, Promise.all/allSettled/race/any, AbortController
- **ES2015-2024**: destructuring, spread, optional chaining, nullish coalescing, dynamic imports
- **Modules**: ESM import/export, dynamic imports, tree-shaking, CommonJS interop
- **Error handling**: async error propagation, unhandledRejection, custom error classes
- **Performance**: memory leaks, debounce, throttle, memoization, WeakMap/WeakRef
---
## Key Patterns & Code
### Event Loop — Execution Order
```javascript
// sync → microtasks (Promises) → macrotasks (setTimeout)
console.log("1"); // sync
setTimeout(() => console.log("4"), 0); // macrotask
Promise.resolve().then(() => console.log("2")); // microtask
console.log("3"); // sync
// Output: 1, 3, 2, 4
// Async/await with proper cancellation
async function fetchUser(id) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);
try {
const res = await fetch(`/api/users/${id}`, {
signal: controller.signal,
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
return await res.json();
} catch (error) {
if (error.name === "AbortError") throw new Error("Request timed out");
throw error;
} finally {
clearTimeout(timeout);
}
}
```
### Concurrent Async Patterns
```javascript
// Run concurrently, fail fast if any fails
const [users, posts] = await Promise.all([fetchUsers(), fetchPosts()]);
// Run concurrently, collect ALL results including failures
const results = await Promise.allSettled([fetchA(), fetchB(), fetchC()]);
const succeeded = results
.filter(r => r.status === "fulfilled")
.map(r => r.value);
const failed = results
.filter(r => r.status === "rejected")
.map(r => r.reason);
// Retry with exponential backoff
async function withRetry(fn, maxAttempts = 3, baseDelay = 1000) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
return await fn();
} catch (error) {
if (attempt === maxAttempts - 1) throw error;
await new Promise(r => setTimeout(r, baseDelay * 2 ** attempt));
}
}
}
```
### Closures & Private State
```javascript
// Factory function with private state
function createCounter(initial = 0) {
let count = initial; // private — not accessible outside
return {
increment: () => ++count,
decrement: () => --count,
reset: () => { count = initial; },
value: () => count,
};
}
// Memoization via closure
const memoize = (fn) => {
const cache = new Map();
return (...args) => {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const result = fn(...args);
cache.set(key, result);
return result;
};
};
// Debounce — delay execution until user stops typing
const debounce = (fn, delay) => {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
};
// Throttle — execute at most once per interval
const throttle = (fn, limit) => {
let lastCall = 0;
return (...args) => {
const now = Date.now();
if (now - lastCall >= limit) {
lastCall = now;
return fn(...args);
}
};
};
```
### Immutable Update Patterns
```javascript
// Never mutate — always create new objects/arrays
const user = { name: "Alice", address: { city: "Cairo", zip: "11511" } };
// Update nested object immutably
const updated = {
...user,
address: { ...user.address, city: "Giza" },
};
// Array immutable operations
const arr = [1, 2, 3, 4, 5];
const added = [...arr, 6]; // add
const removed = arr.filter(x => x !== 3); // remove
const replaced = arr.map(x => x === 3 ? 99 : x); // replace
const sorted = [...arr].sort((a, b) => b - a); // sort without mutation
// Deep clone (modern — handles Date, Map, Set, RegExp)
const deepCopy = structuredClone(original);
```
### Custom Error Classes
```javascript
class AppError extends Error {
constructor(message, code) {
super(message);
this.name = this.constructor.name;
this.code = code;
}
}
class NotFoundError extends AppError {
constructor(resource, id) {
super(`${resource} with id ${id} not found`, "NOT_FOUND");
this.resource = resource;
this.id = id;
}
}
class ValidationError extends AppError {
constructor(field, message) {
super(`Validation failed on ${field}: ${message}`, "VALIDATION_ERROR");
this.field = field;
}
}
// Usage
try {
const user = await getUser(id);
} catch (error) {
if (error instanceof NotFoundError) {
res.status(404).json({ error: error.message });
} else {
throw error; // re-throw unexpected errors
}
}
```
### Modern ES Features
```javascript
// Optional chaining + nullish coalescing
const city = user?.address?.city ?? "Unknown";
const name = config?.user?.name ?? "Guest";
// Destructuring with defaults and renaming
const { name: userName = "Anonymous", age = 0, ...rest } = user;
const [first, second, ...remaining] = array;
// Dynamic imports for code splitting
const { formatDate } = await import("./utils/date.js");
// Object.fromEntries — transform map/entries back to object
const doubled = Object.fromEntries(
Object.entries(prices).map(([key, val]) => [key, val * 2])
);
```
---
## Best Practices
- Use `const` everywhere, `let` when reassignment is needed, never `var`
- Use `===` for equality — never `==`
- Always handle Promise rejections with `.catch()` or `try/catch`
- Treat function arguments as immutable — never mutate them
- Use named functions over anonymous for better stack traces
- Use `structuredClone()` for deep cloning
- Use `WeakMap` for metadata on objects to avoid memory leaks
- Use `AbortController` for cancellable fetch requests
---
## Common Pitfalls
| Pitfall | Problem | Fix |
|---|---|---|
| Floating Promise | Unhandled rejections crash Node.js | Always await or .catch() |
| `this` in callbacks | `this` is undefined or wrong | Use arrow functions or .bind() |
| `==` coercion | `0 == ""` is true | Always use `===` |
| Mutating arguments | Unexpected side effects | Treat args as read-only |
| Sync blocking code | Freezes UI / starves event loop | Use async for all I/O |
| `var` hoisting | Variable accessible before declaration | Use `const`/`let` only |
| Missing error handling | Silent async failures | Always handle rejections |
---
## Related Skills
- **typescript-expert**: For adding type safety to JavaScript
- **nodejs-expert**: For Node.js runtime specifics
- **jest-expert**: For testing JavaScript code
- **webperf-expert**: For JS performance optimization
- **react-expert**: For React with JavaScript
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!