# Javascript Expert

> 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'.

- Skill: `luokai0/javascript-expert` (Agent Skill)
- Install (CLI): `npx skillmds@latest add luokai0/javascript-expert`
- Raw SKILL.md: https://api.skillmd.com/api/skills/luokai0/javascript-expert/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: luokai0 (https://skillmd.com/u/luokai0)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/luokai0/javascript-expert

---


# 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

