Claude Agent Skill · by Wshobson

Modern Javascript Patterns

Modern JavaScript Patterns provides developers with a comprehensive guide to ES6+ features including arrow functions, destructuring, async/await, promises, and

Install
Terminal · npx
$npx skills add https://github.com/wshobson/agents --skill modern-javascript-patterns
Works with Paperclip

How Modern Javascript Patterns fits into a Paperclip company.

Modern Javascript Patterns drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.

S
SaaS FactoryPaired

Pre-configured AI company — 18 agents, 18 skills, one-time purchase.

$27$59
Explore pack
Source file
SKILL.md495 lines
Expand
---name: modern-javascript-patternsdescription: Master ES6+ features including async/await, destructuring, spread operators, arrow functions, promises, modules, iterators, generators, and functional programming patterns for writing clean, efficient JavaScript code. Use when refactoring legacy code, implementing modern patterns, or optimizing JavaScript applications.--- # Modern JavaScript Patterns Comprehensive guide for mastering modern JavaScript (ES6+) features, functional programming patterns, and best practices for writing clean, maintainable, and performant code. ## When to Use This Skill - Refactoring legacy JavaScript to modern syntax- Implementing functional programming patterns- Optimizing JavaScript performance- Writing maintainable and readable code- Working with asynchronous operations- Building modern web applications- Migrating from callbacks to Promises/async-await- Implementing data transformation pipelines ## ES6+ Core Features ### 1. Arrow Functions **Syntax and Use Cases:** ```javascript// Traditional functionfunction add(a, b) {  return a + b;} // Arrow functionconst add = (a, b) => a + b; // Single parameter (parentheses optional)const double = (x) => x * 2; // No parametersconst getRandom = () => Math.random(); // Multiple statements (need curly braces)const processUser = (user) => {  const normalized = user.name.toLowerCase();  return { ...user, name: normalized };}; // Returning objects (wrap in parentheses)const createUser = (name, age) => ({ name, age });``` **Lexical 'this' Binding:** ```javascriptclass Counter {  constructor() {    this.count = 0;  }   // Arrow function preserves 'this' context  increment = () => {    this.count++;  };   // Traditional function loses 'this' in callbacks  incrementTraditional() {    setTimeout(function () {      this.count++; // 'this' is undefined    }, 1000);  }   // Arrow function maintains 'this'  incrementArrow() {    setTimeout(() => {      this.count++; // 'this' refers to Counter instance    }, 1000);  }}``` ### 2. Destructuring **Object Destructuring:** ```javascriptconst user = {  id: 1,  name: "John Doe",  email: "john@example.com",  address: {    city: "New York",    country: "USA",  },}; // Basic destructuringconst { name, email } = user; // Rename variablesconst { name: userName, email: userEmail } = user; // Default valuesconst { age = 25 } = user; // Nested destructuringconst {  address: { city, country },} = user; // Rest operatorconst { id, ...userWithoutId } = user; // Function parametersfunction greet({ name, age = 18 }) {  console.log(`Hello ${name}, you are ${age}`);}greet(user);``` **Array Destructuring:** ```javascriptconst numbers = [1, 2, 3, 4, 5]; // Basic destructuringconst [first, second] = numbers; // Skip elementsconst [, , third] = numbers; // Rest operatorconst [head, ...tail] = numbers; // Swapping variableslet a = 1,  b = 2;[a, b] = [b, a]; // Function return valuesfunction getCoordinates() {  return [10, 20];}const [x, y] = getCoordinates(); // Default valuesconst [one, two, three = 0] = [1, 2];``` ### 3. Spread and Rest Operators **Spread Operator:** ```javascript// Array spreadingconst arr1 = [1, 2, 3];const arr2 = [4, 5, 6];const combined = [...arr1, ...arr2]; // Object spreadingconst defaults = { theme: "dark", lang: "en" };const userPrefs = { theme: "light" };const settings = { ...defaults, ...userPrefs }; // Function argumentsconst numbers = [1, 2, 3];Math.max(...numbers); // Copying arrays/objects (shallow copy)const copy = [...arr1];const objCopy = { ...user }; // Adding items immutablyconst newArr = [...arr1, 4, 5];const newObj = { ...user, age: 30 };``` **Rest Parameters:** ```javascript// Collect function argumentsfunction sum(...numbers) {  return numbers.reduce((total, num) => total + num, 0);}sum(1, 2, 3, 4, 5); // With regular parametersfunction greet(greeting, ...names) {  return `${greeting} ${names.join(", ")}`;}greet("Hello", "John", "Jane", "Bob"); // Object restconst { id, ...userData } = user; // Array restconst [first, ...rest] = [1, 2, 3, 4, 5];``` ### 4. Template Literals ```javascript// Basic usageconst name = "John";const greeting = `Hello, ${name}!`; // Multi-line stringsconst html = `  <div>    <h1>${title}</h1>    <p>${content}</p>  </div>`; // Expression evaluationconst price = 19.99;const total = `Total: $${(price * 1.2).toFixed(2)}`; // Tagged template literalsfunction highlight(strings, ...values) {  return strings.reduce((result, str, i) => {    const value = values[i] || "";    return result + str + `<mark>${value}</mark>`;  }, "");} const name = "John";const age = 30;const html = highlight`Name: ${name}, Age: ${age}`;// Output: "Name: <mark>John</mark>, Age: <mark>30</mark>"``` ### 5. Enhanced Object Literals ```javascriptconst name = "John";const age = 30; // Shorthand property namesconst user = { name, age }; // Shorthand method namesconst calculator = {  add(a, b) {    return a + b;  },  subtract(a, b) {    return a - b;  },}; // Computed property namesconst field = "email";const user = {  name: "John",  [field]: "john@example.com",  [`get${field.charAt(0).toUpperCase()}${field.slice(1)}`]() {    return this[field];  },}; // Dynamic property creationconst createUser = (name, ...props) => {  return props.reduce(    (user, [key, value]) => ({      ...user,      [key]: value,    }),    { name },  );}; const user = createUser("John", ["age", 30], ["email", "john@example.com"]);``` ## Asynchronous Patterns ### 1. Promises **Creating and Using Promises:** ```javascript// Creating a promiseconst fetchUser = (id) => {  return new Promise((resolve, reject) => {    setTimeout(() => {      if (id > 0) {        resolve({ id, name: "John" });      } else {        reject(new Error("Invalid ID"));      }    }, 1000);  });}; // Using promisesfetchUser(1)  .then((user) => console.log(user))  .catch((error) => console.error(error))  .finally(() => console.log("Done")); // Chaining promisesfetchUser(1)  .then((user) => fetchUserPosts(user.id))  .then((posts) => processPosts(posts))  .then((result) => console.log(result))  .catch((error) => console.error(error));``` **Promise Combinators:** ```javascript// Promise.all - Wait for all promisesconst promises = [fetchUser(1), fetchUser(2), fetchUser(3)]; Promise.all(promises)  .then((users) => console.log(users))  .catch((error) => console.error("At least one failed:", error)); // Promise.allSettled - Wait for all, regardless of outcomePromise.allSettled(promises).then((results) => {  results.forEach((result) => {    if (result.status === "fulfilled") {      console.log("Success:", result.value);    } else {      console.log("Error:", result.reason);    }  });}); // Promise.race - First to completePromise.race(promises)  .then((winner) => console.log("First:", winner))  .catch((error) => console.error(error)); // Promise.any - First to succeedPromise.any(promises)  .then((first) => console.log("First success:", first))  .catch((error) => console.error("All failed:", error));``` ### 2. Async/Await **Basic Usage:** ```javascript// Async function always returns a Promiseasync function fetchUser(id) {  const response = await fetch(`/api/users/${id}`);  const user = await response.json();  return user;} // Error handling with try/catchasync function getUserData(id) {  try {    const user = await fetchUser(id);    const posts = await fetchUserPosts(user.id);    return { user, posts };  } catch (error) {    console.error("Error fetching data:", error);    throw error;  }} // Sequential vs Parallel executionasync function sequential() {  const user1 = await fetchUser(1); // Wait  const user2 = await fetchUser(2); // Then wait  return [user1, user2];} async function parallel() {  const [user1, user2] = await Promise.all([fetchUser(1), fetchUser(2)]);  return [user1, user2];}``` **Advanced Patterns:** ```javascript// Async IIFE(async () => {  const result = await someAsyncOperation();  console.log(result);})(); // Async iterationasync function processUsers(userIds) {  for (const id of userIds) {    const user = await fetchUser(id);    await processUser(user);  }} // Top-level await (ES2022)const config = await fetch("/config.json").then((r) => r.json()); // Retry logicasync function fetchWithRetry(url, retries = 3) {  for (let i = 0; i < retries; i++) {    try {      return await fetch(url);    } catch (error) {      if (i === retries - 1) throw error;      await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));    }  }} // Timeout wrapperasync function withTimeout(promise, ms) {  const timeout = new Promise((_, reject) =>    setTimeout(() => reject(new Error("Timeout")), ms),  );  return Promise.race([promise, timeout]);}``` ## Functional Programming Patterns Functional programming in JavaScript centers on pure functions, immutability, and composable transformations. Key topics covered in [references/advanced-patterns.md](references/advanced-patterns.md):- **Array methods** — `map`, `filter`, `reduce`, `find`, `findIndex`, `some`, `every`, `flatMap`, `Array.from`- **Higher-order functions** — custom `forEach`/`map`/`filter`, currying, partial application, memoization- **Composition and piping** — `compose`/`pipe` utilities with practical data transformation examples- **Pure functions and immutability** — immutable array/object operations, deep cloning with `structuredClone` ## Modern Class Features ES2022 classes support private fields (`#field`), static fields, getters/setters, and private methods. See [references/advanced-patterns.md](references/advanced-patterns.md) for a full example with inheritance. ## Modules (ES6) ```javascript// Named exportsexport const PI = 3.14159;export function add(a, b) { return a + b; } // Default exportexport default function multiply(a, b) { return a * b; } // Importimport multiply, { PI, add } from "./math.js"; // Dynamic import (code splitting)const { add } = await import("./math.js");``` For re-exports, namespace imports, and conditional dynamic loading see [references/advanced-patterns.md](references/advanced-patterns.md). ## Iterators and Generators Generators (`function*`) and async generators (`async function*`) enable lazy sequences and async pagination. See [references/advanced-patterns.md](references/advanced-patterns.md) for custom iterator, range generator, fibonacci, and `for await...of` examples. ## Modern Operators ```javascript// Optional chaining — safe property accessconst city = user?.address?.city;const result = obj.method?.(); // Nullish coalescing — default only for null/undefined (not 0 or "")const value = null ?? "default"; // 'default'const zero = 0 ?? "default";    // 0 // Logical assignmenta ??= "default";   // assign if null/undefinedobj.count ||= 1;   // assign if falsyobj.count &&= 2;   // assign if truthy``` ## Performance Optimization See [references/advanced-patterns.md](references/advanced-patterns.md) for debounce, throttle, and lazy evaluation with generators. ## Best Practices 1. **Use const by default**: Only use let when reassignment is needed2. **Prefer arrow functions**: Especially for callbacks3. **Use template literals**: Instead of string concatenation4. **Destructure objects and arrays**: For cleaner code5. **Use async/await**: Instead of Promise chains6. **Avoid mutating data**: Use spread operator and array methods7. **Use optional chaining**: Prevent "Cannot read property of undefined"8. **Use nullish coalescing**: For default values9. **Prefer array methods**: Over traditional loops10. **Use modules**: For better code organization11. **Write pure functions**: Easier to test and reason about12. **Use meaningful variable names**: Self-documenting code13. **Keep functions small**: Single responsibility principle14. **Handle errors properly**: Use try/catch with async/await15. **Use strict mode**: `'use strict'` for better error catching For common pitfalls (this binding, promise anti-patterns, memory leaks), see [references/advanced-patterns.md](references/advanced-patterns.md).