Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Apply modern ES2020+ JavaScript patterns: modules, async/await, optional chaining, and functional idioms.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/details.md
1# modern-javascript-patterns — detailed patterns and worked examples23## ES6+ Core Features45### 1. Arrow Functions67**Syntax and Use Cases:**89```javascript10// Traditional function11function add(a, b) {12return a + b;13}1415// Arrow function16const add = (a, b) => a + b;1718// Single parameter (parentheses optional)19const double = (x) => x * 2;2021// No parameters22const getRandom = () => Math.random();2324// Multiple statements (need curly braces)25const processUser = (user) => {26const normalized = user.name.toLowerCase();27return { ...user, name: normalized };28};2930// Returning objects (wrap in parentheses)31const createUser = (name, age) => ({ name, age });32```3334**Lexical 'this' Binding:**3536```javascript37class Counter {38constructor() {39this.count = 0;40}4142// Arrow function preserves 'this' context43increment = () => {44this.count++;45};4647// Traditional function loses 'this' in callbacks48incrementTraditional() {49setTimeout(function () {50this.count++; // 'this' is undefined51}, 1000);52}5354// Arrow function maintains 'this'55incrementArrow() {56setTimeout(() => {57this.count++; // 'this' refers to Counter instance58}, 1000);59}60}61```6263### 2. Destructuring6465**Object Destructuring:**6667```javascript68const user = {69id: 1,70name: "John Doe",71email: "[email protected]",72address: {73city: "New York",74country: "USA",75},76};7778// Basic destructuring79const { name, email } = user;8081// Rename variables82const { name: userName, email: userEmail } = user;8384// Default values85const { age = 25 } = user;8687// Nested destructuring88const {89address: { city, country },90} = user;9192// Rest operator93const { id, ...userWithoutId } = user;9495// Function parameters96function greet({ name, age = 18 }) {97console.log(`Hello ${name}, you are ${age}`);98}99greet(user);100```101102**Array Destructuring:**103104```javascript105const numbers = [1, 2, 3, 4, 5];106107// Basic destructuring108const [first, second] = numbers;109110// Skip elements111const [, , third] = numbers;112113// Rest operator114const [head, ...tail] = numbers;115116// Swapping variables117let a = 1,118b = 2;119[a, b] = [b, a];120121// Function return values122function getCoordinates() {123return [10, 20];124}125const [x, y] = getCoordinates();126127// Default values128const [one, two, three = 0] = [1, 2];129```130131### 3. Spread and Rest Operators132133**Spread Operator:**134135```javascript136// Array spreading137const arr1 = [1, 2, 3];138const arr2 = [4, 5, 6];139const combined = [...arr1, ...arr2];140141// Object spreading142const defaults = { theme: "dark", lang: "en" };143const userPrefs = { theme: "light" };144const settings = { ...defaults, ...userPrefs };145146// Function arguments147const numbers = [1, 2, 3];148Math.max(...numbers);149150// Copying arrays/objects (shallow copy)151const copy = [...arr1];152const objCopy = { ...user };153154// Adding items immutably155const newArr = [...arr1, 4, 5];156const newObj = { ...user, age: 30 };157```158159**Rest Parameters:**160161```javascript162// Collect function arguments163function sum(...numbers) {164return numbers.reduce((total, num) => total + num, 0);165}166sum(1, 2, 3, 4, 5);167168// With regular parameters169function greet(greeting, ...names) {170return `${greeting} ${names.join(", ")}`;171}172greet("Hello", "John", "Jane", "Bob");173174// Object rest175const { id, ...userData } = user;176177// Array rest178const [first, ...rest] = [1, 2, 3, 4, 5];179```180181### 4. Template Literals182183```javascript184// Basic usage185const name = "John";186const greeting = `Hello, ${name}!`;187188// Multi-line strings189const html = `190<div>191<h1>${title}</h1>192<p>${content}</p>193</div>194`;195196// Expression evaluation197const price = 19.99;198const total = `Total: $${(price * 1.2).toFixed(2)}`;199200// Tagged template literals201function highlight(strings, ...values) {202return strings.reduce((result, str, i) => {203const value = values[i] || "";204return result + str + `<mark>${value}</mark>`;205}, "");206}207208const name = "John";209const age = 30;210const html = highlight`Name: ${name}, Age: ${age}`;211// Output: "Name: <mark>John</mark>, Age: <mark>30</mark>"212```213214### 5. Enhanced Object Literals215216```javascript217const name = "John";218const age = 30;219220// Shorthand property names221const user = { name, age };222223// Shorthand method names224const calculator = {225add(a, b) {226return a + b;227},228subtract(a, b) {229return a - b;230},231};232233// Computed property names234const field = "email";235const user = {236name: "John",237[field]: "[email protected]",238[`get${field.charAt(0).toUpperCase()}${field.slice(1)}`]() {239return this[field];240},241};242243// Dynamic property creation244const createUser = (name, ...props) => {245return props.reduce(246(user, [key, value]) => ({247...user,248[key]: value,249}),250{ name },251);252};253254const user = createUser("John", ["age", 30], ["email", "[email protected]"]);255```256257## Asynchronous Patterns258259### 1. Promises260261**Creating and Using Promises:**262263```javascript264// Creating a promise265const fetchUser = (id) => {266return new Promise((resolve, reject) => {267setTimeout(() => {268if (id > 0) {269resolve({ id, name: "John" });270} else {271reject(new Error("Invalid ID"));272}273}, 1000);274});275};276277// Using promises278fetchUser(1)279.then((user) => console.log(user))280.catch((error) => console.error(error))281.finally(() => console.log("Done"));282283// Chaining promises284fetchUser(1)285.then((user) => fetchUserPosts(user.id))286.then((posts) => processPosts(posts))287.then((result) => console.log(result))288.catch((error) => console.error(error));289```290291**Promise Combinators:**292293```javascript294// Promise.all - Wait for all promises295const promises = [fetchUser(1), fetchUser(2), fetchUser(3)];296297Promise.all(promises)298.then((users) => console.log(users))299.catch((error) => console.error("At least one failed:", error));300301// Promise.allSettled - Wait for all, regardless of outcome302Promise.allSettled(promises).then((results) => {303results.forEach((result) => {304if (result.status === "fulfilled") {305console.log("Success:", result.value);306} else {307console.log("Error:", result.reason);308}309});310});311312// Promise.race - First to complete313Promise.race(promises)314.then((winner) => console.log("First:", winner))315.catch((error) => console.error(error));316317// Promise.any - First to succeed318Promise.any(promises)319.then((first) => console.log("First success:", first))320.catch((error) => console.error("All failed:", error));321```322323### 2. Async/Await324325**Basic Usage:**326327```javascript328// Async function always returns a Promise329async function fetchUser(id) {330const response = await fetch(`/api/users/${id}`);331const user = await response.json();332return user;333}334335// Error handling with try/catch336async function getUserData(id) {337try {338const user = await fetchUser(id);339const posts = await fetchUserPosts(user.id);340return { user, posts };341} catch (error) {342console.error("Error fetching data:", error);343throw error;344}345}346347// Sequential vs Parallel execution348async function sequential() {349const user1 = await fetchUser(1); // Wait350const user2 = await fetchUser(2); // Then wait351return [user1, user2];352}353354async function parallel() {355const [user1, user2] = await Promise.all([fetchUser(1), fetchUser(2)]);356return [user1, user2];357}358```359360**Advanced Patterns:**361362```javascript363// Async IIFE364(async () => {365const result = await someAsyncOperation();366console.log(result);367})();368369// Async iteration370async function processUsers(userIds) {371for (const id of userIds) {372const user = await fetchUser(id);373await processUser(user);374}375}376377// Top-level await (ES2022)378const config = await fetch("/config.json").then((r) => r.json());379380// Retry logic381async function fetchWithRetry(url, retries = 3) {382for (let i = 0; i < retries; i++) {383try {384return await fetch(url);385} catch (error) {386if (i === retries - 1) throw error;387await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));388}389}390}391392// Timeout wrapper393async function withTimeout(promise, ms) {394const timeout = new Promise((_, reject) =>395setTimeout(() => reject(new Error("Timeout")), ms),396);397return Promise.race([promise, timeout]);398}399```400401## Functional Programming Patterns402403Functional programming in JavaScript centers on pure functions, immutability, and composable transformations.404405Key topics covered in [references/advanced-patterns.md](references/advanced-patterns.md):406- **Array methods** — `map`, `filter`, `reduce`, `find`, `findIndex`, `some`, `every`, `flatMap`, `Array.from`407- **Higher-order functions** — custom `forEach`/`map`/`filter`, currying, partial application, memoization408- **Composition and piping** — `compose`/`pipe` utilities with practical data transformation examples409- **Pure functions and immutability** — immutable array/object operations, deep cloning with `structuredClone`410411## Modern Class Features412413ES2022 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.414415## Modules (ES6)416417```javascript418// Named exports419export const PI = 3.14159;420export function add(a, b) { return a + b; }421422// Default export423export default function multiply(a, b) { return a * b; }424425// Import426import multiply, { PI, add } from "./math.js";427428// Dynamic import (code splitting)429const { add } = await import("./math.js");430```431432For re-exports, namespace imports, and conditional dynamic loading see [references/advanced-patterns.md](references/advanced-patterns.md).433434## Iterators and Generators435436Generators (`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.437438## Modern Operators439440```javascript441// Optional chaining — safe property access442const city = user?.address?.city;443const result = obj.method?.();444445// Nullish coalescing — default only for null/undefined (not 0 or "")446const value = null ?? "default"; // 'default'447const zero = 0 ?? "default"; // 0448449// Logical assignment450a ??= "default"; // assign if null/undefined451obj.count ||= 1; // assign if falsy452obj.count &&= 2; // assign if truthy453```454455## Performance Optimization456457See [references/advanced-patterns.md](references/advanced-patterns.md) for debounce, throttle, and lazy evaluation with generators.458