[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6ENDJC6HDRGJXJ3Y5PZPTWM":3,"skill-same:01M6ENDJC6HDRGJXJ3Y5PZPTWM":77},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":52,"repositoryHtmlUrl":53,"repositoryHomepageUrl":6,"ownerHtmlUrl":54,"ownerBlogUrl":6,"ownerDescription":55,"updatedAt":56,"install":57,"resources":70},"01M6ENDJC6HDRGJXJ3Y5PZPTWM","modern-javascript-patterns",null,"Master ES6+ features including async\u002Fawait, 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.","dibstern\u002Fconduit","dibstern","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F16970307?v=4","01M6ENBH1PHAQ5RZZTR2TKTRA7","David Stern","01M6ENBH5ZBECS0MFBF0F10V20",15,"MIT","https:\u002F\u002Fgithub.com\u002Fdibstern\u002Fconduit\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fmodern-javascript-patterns\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"javascript","patterns","modern javascript patterns","functional","writing","es6","operators","promises","clean","master","Legacy","async","modules","refactoring legacy code","use","programming","refactoring","applications","functional programming","code","2026-11-10 10:12:30",false,"---\nname: modern-javascript-patterns\ndescription: Master ES6+ features including async\u002Fawait, 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.\n---\n\n# Modern JavaScript Patterns\n\nComprehensive guide for mastering modern JavaScript (ES6+) features, functional programming patterns, and best practices for writing clean, maintainable, and performant code.\n\n## When to Use This Skill\n\n- Refactoring legacy JavaScript to modern syntax\n- Implementing functional programming patterns\n- Optimizing JavaScript performance\n- Writing maintainable and readable code\n- Working with asynchronous operations\n- Building modern web applications\n- Migrating from callbacks to Promises\u002Fasync-await\n- Implementing data transformation pipelines\n\n## ES6+ Core Features\n\n### 1. Arrow Functions\n\n**Syntax and Use Cases:**\n\n```javascript\n\u002F\u002F Traditional function\nfunction add(a, b) {\n  return a + b;\n}\n\n\u002F\u002F Arrow function\nconst add = (a, b) => a + b;\n\n\u002F\u002F Single parameter (parentheses optional)\nconst double = (x) => x * 2;\n\n\u002F\u002F No parameters\nconst getRandom = () => Math.random();\n\n\u002F\u002F Multiple statements (need curly braces)\nconst processUser = (user) => {\n  const normalized = user.name.toLowerCase();\n  return { ...user, name: normalized };\n};\n\n\u002F\u002F Returning objects (wrap in parentheses)\nconst createUser = (name, age) => ({ name, age });\n```\n\n**Lexical 'this' Binding:**\n\n```javascript\nclass Counter {\n  constructor() {\n    this.count = 0;\n  }\n\n  \u002F\u002F Arrow function preserves 'this' context\n  increment = () => {\n    this.count++;\n  };\n\n  \u002F\u002F Traditional function loses 'this' in callbacks\n  incrementTraditional() {\n    setTimeout(function () {\n      this.count++; \u002F\u002F 'this' is undefined\n    }, 1000);\n  }\n\n  \u002F\u002F Arrow function maintains 'this'\n  incrementArrow() {\n    setTimeout(() => {\n      this.count++; \u002F\u002F 'this' refers to Counter instance\n    }, 1000);\n  }\n}\n```\n\n### 2. Destructuring\n\n**Object Destructuring:**\n\n```javascript\nconst user = {\n  id: 1,\n  name: \"John Doe\",\n  email: \"john@example.com\",\n  address: {\n    city: \"New York\",\n    country: \"USA\",\n  },\n};\n\n\u002F\u002F Basic destructuring\nconst { name, email } = user;\n\n\u002F\u002F Rename variables\nconst { name: userName, email: userEmail } = user;\n\n\u002F\u002F Default values\nconst { age = 25 } = user;\n\n\u002F\u002F Nested destructuring\nconst {\n  address: { city, country },\n} = user;\n\n\u002F\u002F Rest operator\nconst { id, ...userWithoutId } = user;\n\n\u002F\u002F Function parameters\nfunction greet({ name, age = 18 }) {\n  console.log(`Hello ${name}, you are ${age}`);\n}\ngreet(user);\n```\n\n**Array Destructuring:**\n\n```javascript\nconst numbers = [1, 2, 3, 4, 5];\n\n\u002F\u002F Basic destructuring\nconst [first, second] = numbers;\n\n\u002F\u002F Skip elements\nconst [, , third] = numbers;\n\n\u002F\u002F Rest operator\nconst [head, ...tail] = numbers;\n\n\u002F\u002F Swapping variables\nlet a = 1,\n  b = 2;\n[a, b] = [b, a];\n\n\u002F\u002F Function return values\nfunction getCoordinates() {\n  return [10, 20];\n}\nconst [x, y] = getCoordinates();\n\n\u002F\u002F Default values\nconst [one, two, three = 0] = [1, 2];\n```\n\n### 3. Spread and Rest Operators\n\n**Spread Operator:**\n\n```javascript\n\u002F\u002F Array spreading\nconst arr1 = [1, 2, 3];\nconst arr2 = [4, 5, 6];\nconst combined = [...arr1, ...arr2];\n\n\u002F\u002F Object spreading\nconst defaults = { theme: \"dark\", lang: \"en\" };\nconst userPrefs = { theme: \"light\" };\nconst settings = { ...defaults, ...userPrefs };\n\n\u002F\u002F Function arguments\nconst numbers = [1, 2, 3];\nMath.max(...numbers);\n\n\u002F\u002F Copying arrays\u002Fobjects (shallow copy)\nconst copy = [...arr1];\nconst objCopy = { ...user };\n\n\u002F\u002F Adding items immutably\nconst newArr = [...arr1, 4, 5];\nconst newObj = { ...user, age: 30 };\n```\n\n**Rest Parameters:**\n\n```javascript\n\u002F\u002F Collect function arguments\nfunction sum(...numbers) {\n  return numbers.reduce((total, num) => total + num, 0);\n}\nsum(1, 2, 3, 4, 5);\n\n\u002F\u002F With regular parameters\nfunction greet(greeting, ...names) {\n  return `${greeting} ${names.join(\", \")}`;\n}\ngreet(\"Hello\", \"John\", \"Jane\", \"Bob\");\n\n\u002F\u002F Object rest\nconst { id, ...userData } = user;\n\n\u002F\u002F Array rest\nconst [first, ...rest] = [1, 2, 3, 4, 5];\n```\n\n### 4. Template Literals\n\n```javascript\n\u002F\u002F Basic usage\nconst name = \"John\";\nconst greeting = `Hello, ${name}!`;\n\n\u002F\u002F Multi-line strings\nconst html = `\n  \u003Cdiv>\n    \u003Ch1>${title}\u003C\u002Fh1>\n    \u003Cp>${content}\u003C\u002Fp>\n  \u003C\u002Fdiv>\n`;\n\n\u002F\u002F Expression evaluation\nconst price = 19.99;\nconst total = `Total: $${(price * 1.2).toFixed(2)}`;\n\n\u002F\u002F Tagged template literals\nfunction highlight(strings, ...values) {\n  return strings.reduce((result, str, i) => {\n    const value = values[i] || \"\";\n    return result + str + `\u003Cmark>${value}\u003C\u002Fmark>`;\n  }, \"\");\n}\n\nconst name = \"John\";\nconst age = 30;\nconst html = highlight`Name: ${name}, Age: ${age}`;\n\u002F\u002F Output: \"Name: \u003Cmark>John\u003C\u002Fmark>, Age: \u003Cmark>30\u003C\u002Fmark>\"\n```\n\n### 5. Enhanced Object Literals\n\n```javascript\nconst name = \"John\";\nconst age = 30;\n\n\u002F\u002F Shorthand property names\nconst user = { name, age };\n\n\u002F\u002F Shorthand method names\nconst calculator = {\n  add(a, b) {\n    return a + b;\n  },\n  subtract(a, b) {\n    return a - b;\n  },\n};\n\n\u002F\u002F Computed property names\nconst field = \"email\";\nconst user = {\n  name: \"John\",\n  [field]: \"john@example.com\",\n  [`get${field.charAt(0).toUpperCase()}${field.slice(1)}`]() {\n    return this[field];\n  },\n};\n\n\u002F\u002F Dynamic property creation\nconst createUser = (name, ...props) => {\n  return props.reduce(\n    (user, [key, value]) => ({\n      ...user,\n      [key]: value,\n    }),\n    { name },\n  );\n};\n\nconst user = createUser(\"John\", [\"age\", 30], [\"email\", \"john@example.com\"]);\n```\n\n## Asynchronous Patterns\n\n### 1. Promises\n\n**Creating and Using Promises:**\n\n```javascript\n\u002F\u002F Creating a promise\nconst fetchUser = (id) => {\n  return new Promise((resolve, reject) => {\n    setTimeout(() => {\n      if (id > 0) {\n        resolve({ id, name: \"John\" });\n      } else {\n        reject(new Error(\"Invalid ID\"));\n      }\n    }, 1000);\n  });\n};\n\n\u002F\u002F Using promises\nfetchUser(1)\n  .then((user) => console.log(user))\n  .catch((error) => console.error(error))\n  .finally(() => console.log(\"Done\"));\n\n\u002F\u002F Chaining promises\nfetchUser(1)\n  .then((user) => fetchUserPosts(user.id))\n  .then((posts) => processPosts(posts))\n  .then((result) => console.log(result))\n  .catch((error) => console.error(error));\n```\n\n**Promise Combinators:**\n\n```javascript\n\u002F\u002F Promise.all - Wait for all promises\nconst promises = [fetchUser(1), fetchUser(2), fetchUser(3)];\n\nPromise.all(promises)\n  .then((users) => console.log(users))\n  .catch((error) => console.error(\"At least one failed:\", error));\n\n\u002F\u002F Promise.allSettled - Wait for all, regardless of outcome\nPromise.allSettled(promises).then((results) => {\n  results.forEach((result) => {\n    if (result.status === \"fulfilled\") {\n      console.log(\"Success:\", result.value);\n    } else {\n      console.log(\"Error:\", result.reason);\n    }\n  });\n});\n\n\u002F\u002F Promise.race - First to complete\nPromise.race(promises)\n  .then((winner) => console.log(\"First:\", winner))\n  .catch((error) => console.error(error));\n\n\u002F\u002F Promise.any - First to succeed\nPromise.any(promises)\n  .then((first) => console.log(\"First success:\", first))\n  .catch((error) => console.error(\"All failed:\", error));\n```\n\n### 2. Async\u002FAwait\n\n**Basic Usage:**\n\n```javascript\n\u002F\u002F Async function always returns a Promise\nasync function fetchUser(id) {\n  const response = await fetch(`\u002Fapi\u002Fusers\u002F${id}`);\n  const user = await response.json();\n  return user;\n}\n\n\u002F\u002F Error handling with try\u002Fcatch\nasync function getUserData(id) {\n  try {\n    const user = await fetchUser(id);\n    const posts = await fetchUserPosts(user.id);\n    return { user, posts };\n  } catch (error) {\n    console.error(\"Error fetching data:\", error);\n    throw error;\n  }\n}\n\n\u002F\u002F Sequential vs Parallel execution\nasync function sequential() {\n  const user1 = await fetchUser(1); \u002F\u002F Wait\n  const user2 = await fetchUser(2); \u002F\u002F Then wait\n  return [user1, user2];\n}\n\nasync function parallel() {\n  const [user1, user2] = await Promise.all([fetchUser(1), fetchUser(2)]);\n  return [user1, user2];\n}\n```\n\n**Advanced Patterns:**\n\n```javascript\n\u002F\u002F Async IIFE\n(async () => {\n  const result = await someAsyncOperation();\n  console.log(result);\n})();\n\n\u002F\u002F Async iteration\nasync function processUsers(userIds) {\n  for (const id of userIds) {\n    const user = await fetchUser(id);\n    await processUser(user);\n  }\n}\n\n\u002F\u002F Top-level await (ES2022)\nconst config = await fetch(\"\u002Fconfig.json\").then((r) => r.json());\n\n\u002F\u002F Retry logic\nasync function fetchWithRetry(url, retries = 3) {\n  for (let i = 0; i \u003C retries; i++) {\n    try {\n      return await fetch(url);\n    } catch (error) {\n      if (i === retries - 1) throw error;\n      await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));\n    }\n  }\n}\n\n\u002F\u002F Timeout wrapper\nasync function withTimeout(promise, ms) {\n  const timeout = new Promise((_, reject) =>\n    setTimeout(() => reject(new Error(\"Timeout\")), ms),\n  );\n  return Promise.race([promise, timeout]);\n}\n```\n\n## Functional Programming Patterns\n\n### 1. Array Methods\n\n**Map, Filter, Reduce:**\n\n```javascript\nconst users = [\n  { id: 1, name: \"John\", age: 30, active: true },\n  { id: 2, name: \"Jane\", age: 25, active: false },\n  { id: 3, name: \"Bob\", age: 35, active: true },\n];\n\n\u002F\u002F Map - Transform array\nconst names = users.map((user) => user.name);\nconst upperNames = users.map((user) => user.name.toUpperCase());\n\n\u002F\u002F Filter - Select elements\nconst activeUsers = users.filter((user) => user.active);\nconst adults = users.filter((user) => user.age >= 18);\n\n\u002F\u002F Reduce - Aggregate data\nconst totalAge = users.reduce((sum, user) => sum + user.age, 0);\nconst avgAge = totalAge \u002F users.length;\n\n\u002F\u002F Group by property\nconst byActive = users.reduce((groups, user) => {\n  const key = user.active ? \"active\" : \"inactive\";\n  return {\n    ...groups,\n    [key]: [...(groups[key] || []), user],\n  };\n}, {});\n\n\u002F\u002F Chaining methods\nconst result = users\n  .filter((user) => user.active)\n  .map((user) => user.name)\n  .sort()\n  .join(\", \");\n```\n\n**Advanced Array Methods:**\n\n```javascript\n\u002F\u002F Find - First matching element\nconst user = users.find((u) => u.id === 2);\n\n\u002F\u002F FindIndex - Index of first match\nconst index = users.findIndex((u) => u.name === \"Jane\");\n\n\u002F\u002F Some - At least one matches\nconst hasActive = users.some((u) => u.active);\n\n\u002F\u002F Every - All match\nconst allAdults = users.every((u) => u.age >= 18);\n\n\u002F\u002F FlatMap - Map and flatten\nconst userTags = [\n  { name: \"John\", tags: [\"admin\", \"user\"] },\n  { name: \"Jane\", tags: [\"user\"] },\n];\nconst allTags = userTags.flatMap((u) => u.tags);\n\n\u002F\u002F From - Create array from iterable\nconst str = \"hello\";\nconst chars = Array.from(str);\nconst numbers = Array.from({ length: 5 }, (_, i) => i + 1);\n\n\u002F\u002F Of - Create array from arguments\nconst arr = Array.of(1, 2, 3);\n```\n\n### 2. Higher-Order Functions\n\n**Functions as Arguments:**\n\n```javascript\n\u002F\u002F Custom forEach\nfunction forEach(array, callback) {\n  for (let i = 0; i \u003C array.length; i++) {\n    callback(array[i], i, array);\n  }\n}\n\n\u002F\u002F Custom map\nfunction map(array, transform) {\n  const result = [];\n  for (const item of array) {\n    result.push(transform(item));\n  }\n  return result;\n}\n\n\u002F\u002F Custom filter\nfunction filter(array, predicate) {\n  const result = [];\n  for (const item of array) {\n    if (predicate(item)) {\n      result.push(item);\n    }\n  }\n  return result;\n}\n```\n\n**Functions Returning Functions:**\n\n```javascript\n\u002F\u002F Currying\nconst multiply = (a) => (b) => a * b;\nconst double = multiply(2);\nconst triple = multiply(3);\n\nconsole.log(double(5)); \u002F\u002F 10\nconsole.log(triple(5)); \u002F\u002F 15\n\n\u002F\u002F Partial application\nfunction partial(fn, ...args) {\n  return (...moreArgs) => fn(...args, ...moreArgs);\n}\n\nconst add = (a, b, c) => a + b + c;\nconst add5 = partial(add, 5);\nconsole.log(add5(3, 2)); \u002F\u002F 10\n\n\u002F\u002F Memoization\nfunction memoize(fn) {\n  const cache = new Map();\n  return (...args) => {\n    const key = JSON.stringify(args);\n    if (cache.has(key)) {\n      return cache.get(key);\n    }\n    const result = fn(...args);\n    cache.set(key, result);\n    return result;\n  };\n}\n\nconst fibonacci = memoize((n) => {\n  if (n \u003C= 1) return n;\n  return fibonacci(n - 1) + fibonacci(n - 2);\n});\n```\n\n### 3. Composition and Piping\n\n```javascript\n\u002F\u002F Function composition\nconst compose =\n  (...fns) =>\n  (x) =>\n    fns.reduceRight((acc, fn) => fn(acc), x);\n\nconst pipe =\n  (...fns) =>\n  (x) =>\n    fns.reduce((acc, fn) => fn(acc), x);\n\n\u002F\u002F Example usage\nconst addOne = (x) => x + 1;\nconst double = (x) => x * 2;\nconst square = (x) => x * x;\n\nconst composed = compose(square, double, addOne);\nconsole.log(composed(3)); \u002F\u002F ((3 + 1) * 2)^2 = 64\n\nconst piped = pipe(addOne, double, square);\nconsole.log(piped(3)); \u002F\u002F ((3 + 1) * 2)^2 = 64\n\n\u002F\u002F Practical example\nconst processUser = pipe(\n  (user) => ({ ...user, name: user.name.trim() }),\n  (user) => ({ ...user, email: user.email.toLowerCase() }),\n  (user) => ({ ...user, age: parseInt(user.age) }),\n);\n\nconst user = processUser({\n  name: \"  John  \",\n  email: \"JOHN@EXAMPLE.COM\",\n  age: \"30\",\n});\n```\n\n### 4. Pure Functions and Immutability\n\n```javascript\n\u002F\u002F Impure function (modifies input)\nfunction addItemImpure(cart, item) {\n  cart.items.push(item);\n  cart.total += item.price;\n  return cart;\n}\n\n\u002F\u002F Pure function (no side effects)\nfunction addItemPure(cart, item) {\n  return {\n    ...cart,\n    items: [...cart.items, item],\n    total: cart.total + item.price,\n  };\n}\n\n\u002F\u002F Immutable array operations\nconst numbers = [1, 2, 3, 4, 5];\n\n\u002F\u002F Add to array\nconst withSix = [...numbers, 6];\n\n\u002F\u002F Remove from array\nconst withoutThree = numbers.filter((n) => n !== 3);\n\n\u002F\u002F Update array element\nconst doubled = numbers.map((n) => (n === 3 ? n * 2 : n));\n\n\u002F\u002F Immutable object operations\nconst user = { name: \"John\", age: 30 };\n\n\u002F\u002F Update property\nconst olderUser = { ...user, age: 31 };\n\n\u002F\u002F Add property\nconst withEmail = { ...user, email: \"john@example.com\" };\n\n\u002F\u002F Remove property\nconst { age, ...withoutAge } = user;\n\n\u002F\u002F Deep cloning (simple approach)\nconst deepClone = (obj) => JSON.parse(JSON.stringify(obj));\n\n\u002F\u002F Better deep cloning\nconst structuredClone = (obj) => globalThis.structuredClone(obj);\n```\n\n## Modern Class Features\n\n```javascript\n\u002F\u002F Class syntax\nclass User {\n  \u002F\u002F Private fields\n  #password;\n\n  \u002F\u002F Public fields\n  id;\n  name;\n\n  \u002F\u002F Static field\n  static count = 0;\n\n  constructor(id, name, password) {\n    this.id = id;\n    this.name = name;\n    this.#password = password;\n    User.count++;\n  }\n\n  \u002F\u002F Public method\n  greet() {\n    return `Hello, ${this.name}`;\n  }\n\n  \u002F\u002F Private method\n  #hashPassword(password) {\n    return `hashed_${password}`;\n  }\n\n  \u002F\u002F Getter\n  get displayName() {\n    return this.name.toUpperCase();\n  }\n\n  \u002F\u002F Setter\n  set password(newPassword) {\n    this.#password = this.#hashPassword(newPassword);\n  }\n\n  \u002F\u002F Static method\n  static create(id, name, password) {\n    return new User(id, name, password);\n  }\n}\n\n\u002F\u002F Inheritance\nclass Admin extends User {\n  constructor(id, name, password, role) {\n    super(id, name, password);\n    this.role = role;\n  }\n\n  greet() {\n    return `${super.greet()}, I'm an admin`;\n  }\n}\n```\n\n## Modules (ES6)\n\n```javascript\n\u002F\u002F Exporting\n\u002F\u002F math.js\nexport const PI = 3.14159;\nexport function add(a, b) {\n  return a + b;\n}\nexport class Calculator {\n  \u002F\u002F ...\n}\n\n\u002F\u002F Default export\nexport default function multiply(a, b) {\n  return a * b;\n}\n\n\u002F\u002F Importing\n\u002F\u002F app.js\nimport multiply, { PI, add, Calculator } from \".\u002Fmath.js\";\n\n\u002F\u002F Rename imports\nimport { add as sum } from \".\u002Fmath.js\";\n\n\u002F\u002F Import all\nimport * as Math from \".\u002Fmath.js\";\n\n\u002F\u002F Dynamic imports\nconst module = await import(\".\u002Fmath.js\");\nconst { add } = await import(\".\u002Fmath.js\");\n\n\u002F\u002F Conditional loading\nif (condition) {\n  const module = await import(\".\u002Ffeature.js\");\n  module.init();\n}\n```\n\n## Iterators and Generators\n\n```javascript\n\u002F\u002F Custom iterator\nconst range = {\n  from: 1,\n  to: 5,\n\n  [Symbol.iterator]() {\n    return {\n      current: this.from,\n      last: this.to,\n\n      next() {\n        if (this.current \u003C= this.last) {\n          return { done: false, value: this.current++ };\n        } else {\n          return { done: true };\n        }\n      },\n    };\n  },\n};\n\nfor (const num of range) {\n  console.log(num); \u002F\u002F 1, 2, 3, 4, 5\n}\n\n\u002F\u002F Generator function\nfunction* rangeGenerator(from, to) {\n  for (let i = from; i \u003C= to; i++) {\n    yield i;\n  }\n}\n\nfor (const num of rangeGenerator(1, 5)) {\n  console.log(num);\n}\n\n\u002F\u002F Infinite generator\nfunction* fibonacci() {\n  let [prev, curr] = [0, 1];\n  while (true) {\n    yield curr;\n    [prev, curr] = [curr, prev + curr];\n  }\n}\n\n\u002F\u002F Async generator\nasync function* fetchPages(url) {\n  let page = 1;\n  while (true) {\n    const response = await fetch(`${url}?page=${page}`);\n    const data = await response.json();\n    if (data.length === 0) break;\n    yield data;\n    page++;\n  }\n}\n\nfor await (const page of fetchPages(\"\u002Fapi\u002Fusers\")) {\n  console.log(page);\n}\n```\n\n## Modern Operators\n\n```javascript\n\u002F\u002F Optional chaining\nconst user = { name: \"John\", address: { city: \"NYC\" } };\nconst city = user?.address?.city;\nconst zipCode = user?.address?.zipCode; \u002F\u002F undefined\n\n\u002F\u002F Function call\nconst result = obj.method?.();\n\n\u002F\u002F Array access\nconst first = arr?.[0];\n\n\u002F\u002F Nullish coalescing\nconst value = null ?? \"default\"; \u002F\u002F 'default'\nconst value = undefined ?? \"default\"; \u002F\u002F 'default'\nconst value = 0 ?? \"default\"; \u002F\u002F 0 (not 'default')\nconst value = \"\" ?? \"default\"; \u002F\u002F '' (not 'default')\n\n\u002F\u002F Logical assignment\nlet a = null;\na ??= \"default\"; \u002F\u002F a = 'default'\n\nlet b = 5;\nb ??= 10; \u002F\u002F b = 5 (unchanged)\n\nlet obj = { count: 0 };\nobj.count ||= 1; \u002F\u002F obj.count = 1\nobj.count &&= 2; \u002F\u002F obj.count = 2\n```\n\n## Performance Optimization\n\n```javascript\n\u002F\u002F Debounce\nfunction debounce(fn, delay) {\n  let timeoutId;\n  return (...args) => {\n    clearTimeout(timeoutId);\n    timeoutId = setTimeout(() => fn(...args), delay);\n  };\n}\n\nconst searchDebounced = debounce(search, 300);\n\n\u002F\u002F Throttle\nfunction throttle(fn, limit) {\n  let inThrottle;\n  return (...args) => {\n    if (!inThrottle) {\n      fn(...args);\n      inThrottle = true;\n      setTimeout(() => (inThrottle = false), limit);\n    }\n  };\n}\n\nconst scrollThrottled = throttle(handleScroll, 100);\n\n\u002F\u002F Lazy evaluation\nfunction* lazyMap(iterable, transform) {\n  for (const item of iterable) {\n    yield transform(item);\n  }\n}\n\n\u002F\u002F Use only what you need\nconst numbers = [1, 2, 3, 4, 5];\nconst doubled = lazyMap(numbers, (x) => x * 2);\nconst first = doubled.next().value; \u002F\u002F Only computes first value\n```\n\n## Best Practices\n\n1. **Use const by default**: Only use let when reassignment is needed\n2. **Prefer arrow functions**: Especially for callbacks\n3. **Use template literals**: Instead of string concatenation\n4. **Destructure objects and arrays**: For cleaner code\n5. **Use async\u002Fawait**: Instead of Promise chains\n6. **Avoid mutating data**: Use spread operator and array methods\n7. **Use optional chaining**: Prevent \"Cannot read property of undefined\"\n8. **Use nullish coalescing**: For default values\n9. **Prefer array methods**: Over traditional loops\n10. **Use modules**: For better code organization\n11. **Write pure functions**: Easier to test and reason about\n12. **Use meaningful variable names**: Self-documenting code\n13. **Keep functions small**: Single responsibility principle\n14. **Handle errors properly**: Use try\u002Fcatch with async\u002Fawait\n15. **Use strict mode**: `'use strict'` for better error catching\n\n## Common Pitfalls\n\n1. **this binding confusion**: Use arrow functions or bind()\n2. **Async\u002Fawait without error handling**: Always use try\u002Fcatch\n3. **Promise creation unnecessary**: Don't wrap already async functions\n4. **Mutation of objects**: Use spread operator or Object.assign()\n5. **Forgetting await**: Async functions return promises\n6. **Blocking event loop**: Avoid synchronous operations\n7. **Memory leaks**: Clean up event listeners and timers\n8. **Not handling promise rejections**: Use catch() or try\u002Fcatch\n\n## Resources\n\n- **MDN Web Docs**: https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\n- **JavaScript.info**: https:\u002F\u002Fjavascript.info\u002F\n- **You Don't Know JS**: https:\u002F\u002Fgithub.com\u002Fgetify\u002FYou-Dont-Know-JS\n- **Eloquent JavaScript**: https:\u002F\u002Feloquentjavascript.net\u002F\n- **ES6 Features**: http:\u002F\u002Fes6-features.org\u002F\n","# Modern JavaScript Patterns\n\nComprehensive guide for mastering modern JavaScript (ES6+) features, functional programming patterns, and best practices for writing clean, maintainable, and performant code.\n\n## When to Use This Skill\n\n- Refactoring legacy JavaScript to modern syntax\n- Implementing functional programming patterns\n- Optimizing JavaScript performance\n- Writing maintainable and readable code\n- Working with asynchronous operations\n- Building modern web applications\n- Migrating from callbacks to Promises\u002Fasync-await\n- Implementing data transformation pipelines\n\n## ES6+ Core Features\n\n### 1. Arrow Functions\n\n**Syntax and Use Cases:**\n\n```javascript\n\u002F\u002F Traditional function\nfunction add(a, b) {\n  return a + b;\n}\n\n\u002F\u002F Arrow function\nconst add = (a, b) => a + b;\n\n\u002F\u002F Single parameter (parentheses optional)\nconst double = (x) => x * 2;\n\n\u002F\u002F No parameters\nconst getRandom = () => Math.random();\n\n\u002F\u002F Multiple statements (need curly braces)\nconst processUser = (user) => {\n  const normalized = user.name.toLowerCase();\n  return { ...user, name: normalized };\n};\n\n\u002F\u002F Returning objects (wrap in parentheses)\nconst createUser = (name, age) => ({ name, age });\n```\n\n**Lexical 'this' Binding:**\n\n```javascript\nclass Counter {\n  constructor() {\n    this.count = 0;\n  }\n\n  \u002F\u002F Arrow function preserves 'this' context\n  increment = () => {\n    this.count++;\n  };\n\n  \u002F\u002F Traditional function loses 'this' in callbacks\n  incrementTraditional() {\n    setTimeout(function () {\n      this.count++; \u002F\u002F 'this' is undefined\n    }, 1000);\n  }\n\n  \u002F\u002F Arrow function maintains 'this'\n  incrementArrow() {\n    setTimeout(() => {\n      this.count++; \u002F\u002F 'this' refers to Counter instance\n    }, 1000);\n  }\n}\n```\n\n### 2. Destructuring\n\n**Object Destructuring:**\n\n```javascript\nconst user = {\n  id: 1,\n  name: \"John Doe\",\n  email: \"john@example.com\",\n  address: {\n    city: \"New York\",\n    country: \"USA\",\n  },\n};\n\n\u002F\u002F Basic destructuring\nconst { name, email } = user;\n\n\u002F\u002F Rename variables\nconst { name: userName, email: userEmail } = user;\n\n\u002F\u002F Default values\nconst { age = 25 } = user;\n\n\u002F\u002F Nested destructuring\nconst {\n  address: { city, country },\n} = user;\n\n\u002F\u002F Rest operator\nconst { id, ...userWithoutId } = user;\n\n\u002F\u002F Function parameters\nfunction greet({ name, age = 18 }) {\n  console.log(`Hello ${name}, you are ${age}`);\n}\ngreet(user);\n```\n\n**Array Destructuring:**\n\n```javascript\nconst numbers = [1, 2, 3, 4, 5];\n\n\u002F\u002F Basic destructuring\nconst [first, second] = numbers;\n\n\u002F\u002F Skip elements\nconst [, , third] = numbers;\n\n\u002F\u002F Rest operator\nconst [head, ...tail] = numbers;\n\n\u002F\u002F Swapping variables\nlet a = 1,\n  b = 2;\n[a, b] = [b, a];\n\n\u002F\u002F Function return values\nfunction getCoordinates() {\n  return [10, 20];\n}\nconst [x, y] = getCoordinates();\n\n\u002F\u002F Default values\nconst [one, two, three = 0] = [1, 2];\n```\n\n### 3. Spread and Rest Operators\n\n**Spread Operator:**\n\n```javascript\n\u002F\u002F Array spreading\nconst arr1 = [1, 2, 3];\nconst arr2 = [4, 5, 6];\nconst combined = [...arr1, ...arr2];\n\n\u002F\u002F Object spreading\nconst defaults = { theme: \"dark\", lang: \"en\" };\nconst userPrefs = { theme: \"light\" };\nconst settings = { ...defaults, ...userPrefs };\n\n\u002F\u002F Function arguments\nconst numbers = [1, 2, 3];\nMath.max(...numbers);\n\n\u002F\u002F Copying arrays\u002Fobjects (shallow copy)\nconst copy = [...arr1];\nconst objCopy = { ...user };\n\n\u002F\u002F Adding items immutably\nconst newArr = [...arr1, 4, 5];\nconst newObj = { ...user, age: 30 };\n```\n\n**Rest Parameters:**\n\n```javascript\n\u002F\u002F Collect function arguments\nfunction sum(...numbers) {\n  return numbers.reduce((total, num) => total + num, 0);\n}\nsum(1, 2, 3, 4, 5);\n\n\u002F\u002F With regular parameters\nfunction greet(greeting, ...names) {\n  return `${greeting} ${names.join(\", \")}`;\n}\ngreet(\"Hello\", \"John\", \"Jane\", \"Bob\");\n\n\u002F\u002F Object rest\nconst { id, ...userData } = user;\n\n\u002F\u002F Array rest\nconst [first, ...rest] = [1, 2, 3, 4, 5];\n```\n\n### 4. Template Literals\n\n```javascript\n\u002F\u002F Basic usage\nconst name = \"John\";\nconst greeting = `Hello, ${name}!`;\n\n\u002F\u002F Multi-line strings\nconst html = `\n  \u003Cdiv>\n    \u003Ch1>${title}\u003C\u002Fh1>\n    \u003Cp>${content}\u003C\u002Fp>\n  \u003C\u002Fdiv>\n`;\n\n\u002F\u002F Expression evaluation\nconst price = 19.99;\nconst total = `Total: $${(price * 1.2).toFixed(2)}`;\n\n\u002F\u002F Tagged template literals\nfunction highlight(strings, ...values) {\n  return strings.reduce((result, str, i) => {\n    const value = values[i] || \"\";\n    return result + str + `\u003Cmark>${value}\u003C\u002Fmark>`;\n  }, \"\");\n}\n\nconst name = \"John\";\nconst age = 30;\nconst html = highlight`Name: ${name}, Age: ${age}`;\n\u002F\u002F Output: \"Name: \u003Cmark>John\u003C\u002Fmark>, Age: \u003Cmark>30\u003C\u002Fmark>\"\n```\n\n### 5. Enhanced Object Literals\n\n```javascript\nconst name = \"John\";\nconst age = 30;\n\n\u002F\u002F Shorthand property names\nconst user = { name, age };\n\n\u002F\u002F Shorthand method names\nconst calculator = {\n  add(a, b) {\n    return a + b;\n  },\n  subtract(a, b) {\n    return a - b;\n  },\n};\n\n\u002F\u002F Computed property names\nconst field = \"email\";\nconst user = {\n  name: \"John\",\n  [field]: \"john@example.com\",\n  [`get${field.charAt(0).toUpperCase()}${field.slice(1)}`]() {\n    return this[field];\n  },\n};\n\n\u002F\u002F Dynamic property creation\nconst createUser = (name, ...props) => {\n  return props.reduce(\n    (user, [key, value]) => ({\n      ...user,\n      [key]: value,\n    }),\n    { name },\n  );\n};\n\nconst user = createUser(\"John\", [\"age\", 30], [\"email\", \"john@example.com\"]);\n```\n\n## Asynchronous Patterns\n\n### 1. Promises\n\n**Creating and Using Promises:**\n\n```javascript\n\u002F\u002F Creating a promise\nconst fetchUser = (id) => {\n  return new Promise((resolve, reject) => {\n    setTimeout(() => {\n      if (id > 0) {\n        resolve({ id, name: \"John\" });\n      } else {\n        reject(new Error(\"Invalid ID\"));\n      }\n    }, 1000);\n  });\n};\n\n\u002F\u002F Using promises\nfetchUser(1)\n  .then((user) => console.log(user))\n  .catch((error) => console.error(error))\n  .finally(() => console.log(\"Done\"));\n\n\u002F\u002F Chaining promises\nfetchUser(1)\n  .then((user) => fetchUserPosts(user.id))\n  .then((posts) => processPosts(posts))\n  .then((result) => console.log(result))\n  .catch((error) => console.error(error));\n```\n\n**Promise Combinators:**\n\n```javascript\n\u002F\u002F Promise.all - Wait for all promises\nconst promises = [fetchUser(1), fetchUser(2), fetchUser(3)];\n\nPromise.all(promises)\n  .then((users) => console.log(users))\n  .catch((error) => console.error(\"At least one failed:\", error));\n\n\u002F\u002F Promise.allSettled - Wait for all, regardless of outcome\nPromise.allSettled(promises).then((results) => {\n  results.forEach((result) => {\n    if (result.status === \"fulfilled\") {\n      console.log(\"Success:\", result.value);\n    } else {\n      console.log(\"Error:\", result.reason);\n    }\n  });\n});\n\n\u002F\u002F Promise.race - First to complete\nPromise.race(promises)\n  .then((winner) => console.log(\"First:\", winner))\n  .catch((error) => console.error(error));\n\n\u002F\u002F Promise.any - First to succeed\nPromise.any(promises)\n  .then((first) => console.log(\"First success:\", first))\n  .catch((error) => console.error(\"All failed:\", error));\n```\n\n### 2. Async\u002FAwait\n\n**Basic Usage:**\n\n```javascript\n\u002F\u002F Async function always returns a Promise\nasync function fetchUser(id) {\n  const response = await fetch(`\u002Fapi\u002Fusers\u002F${id}`);\n  const user = await response.json();\n  return user;\n}\n\n\u002F\u002F Error handling with try\u002Fcatch\nasync function getUserData(id) {\n  try {\n    const user = await fetchUser(id);\n    const posts = await fetchUserPosts(user.id);\n    return { user, posts };\n  } catch (error) {\n    console.error(\"Error fetching data:\", error);\n    throw error;\n  }\n}\n\n\u002F\u002F Sequential vs Parallel execution\nasync function sequential() {\n  const user1 = await fetchUser(1); \u002F\u002F Wait\n  const user2 = await fetchUser(2); \u002F\u002F Then wait\n  return [user1, user2];\n}\n\nasync function parallel() {\n  const [user1, user2] = await Promise.all([fetchUser(1), fetchUser(2)]);\n  return [user1, user2];\n}\n```\n\n**Advanced Patterns:**\n\n```javascript\n\u002F\u002F Async IIFE\n(async () => {\n  const result = await someAsyncOperation();\n  console.log(result);\n})();\n\n\u002F\u002F Async iteration\nasync function processUsers(userIds) {\n  for (const id of userIds) {\n    const user = await fetchUser(id);\n    await processUser(user);\n  }\n}\n\n\u002F\u002F Top-level await (ES2022)\nconst config = await fetch(\"\u002Fconfig.json\").then((r) => r.json());\n\n\u002F\u002F Retry logic\nasync function fetchWithRetry(url, retries = 3) {\n  for (let i = 0; i \u003C retries; i++) {\n    try {\n      return await fetch(url);\n    } catch (error) {\n      if (i === retries - 1) throw error;\n      await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));\n    }\n  }\n}\n\n\u002F\u002F Timeout wrapper\nasync function withTimeout(promise, ms) {\n  const timeout = new Promise((_, reject) =>\n    setTimeout(() => reject(new Error(\"Timeout\")), ms),\n  );\n  return Promise.race([promise, timeout]);\n}\n```\n\n## Functional Programming Patterns\n\n### 1. Array Methods\n\n**Map, Filter, Reduce:**\n\n```javascript\nconst users = [\n  { id: 1, name: \"John\", age: 30, active: true },\n  { id: 2, name: \"Jane\", age: 25, active: false },\n  { id: 3, name: \"Bob\", age: 35, active: true },\n];\n\n\u002F\u002F Map - Transform array\nconst names = users.map((user) => user.name);\nconst upperNames = users.map((user) => user.name.toUpperCase());\n\n\u002F\u002F Filter - Select elements\nconst activeUsers = users.filter((user) => user.active);\nconst adults = users.filter((user) => user.age >= 18);\n\n\u002F\u002F Reduce - Aggregate data\nconst totalAge = users.reduce((sum, user) => sum + user.age, 0);\nconst avgAge = totalAge \u002F users.length;\n\n\u002F\u002F Group by property\nconst byActive = users.reduce((groups, user) => {\n  const key = user.active ? \"active\" : \"inactive\";\n  return {\n    ...groups,\n    [key]: [...(groups[key] || []), user],\n  };\n}, {});\n\n\u002F\u002F Chaining methods\nconst result = users\n  .filter((user) => user.active)\n  .map((user) => user.name)\n  .sort()\n  .join(\", \");\n```\n\n**Advanced Array Methods:**\n\n```javascript\n\u002F\u002F Find - First matching element\nconst user = users.find((u) => u.id === 2);\n\n\u002F\u002F FindIndex - Index of first match\nconst index = users.findIndex((u) => u.name === \"Jane\");\n\n\u002F\u002F Some - At least one matches\nconst hasActive = users.some((u) => u.active);\n\n\u002F\u002F Every - All match\nconst allAdults = users.every((u) => u.age >= 18);\n\n\u002F\u002F FlatMap - Map and flatten\nconst userTags = [\n  { name: \"John\", tags: [\"admin\", \"user\"] },\n  { name: \"Jane\", tags: [\"user\"] },\n];\nconst allTags = userTags.flatMap((u) => u.tags);\n\n\u002F\u002F From - Create array from iterable\nconst str = \"hello\";\nconst chars = Array.from(str);\nconst numbers = Array.from({ length: 5 }, (_, i) => i + 1);\n\n\u002F\u002F Of - Create array from arguments\nconst arr = Array.of(1, 2, 3);\n```\n\n### 2. Higher-Order Functions\n\n**Functions as Arguments:**\n\n```javascript\n\u002F\u002F Custom forEach\nfunction forEach(array, callback) {\n  for (let i = 0; i \u003C array.length; i++) {\n    callback(array[i], i, array);\n  }\n}\n\n\u002F\u002F Custom map\nfunction map(array, transform) {\n  const result = [];\n  for (const item of array) {\n    result.push(transform(item));\n  }\n  return result;\n}\n\n\u002F\u002F Custom filter\nfunction filter(array, predicate) {\n  const result = [];\n  for (const item of array) {\n    if (predicate(item)) {\n      result.push(item);\n    }\n  }\n  return result;\n}\n```\n\n**Functions Returning Functions:**\n\n```javascript\n\u002F\u002F Currying\nconst multiply = (a) => (b) => a * b;\nconst double = multiply(2);\nconst triple = multiply(3);\n\nconsole.log(double(5)); \u002F\u002F 10\nconsole.log(triple(5)); \u002F\u002F 15\n\n\u002F\u002F Partial application\nfunction partial(fn, ...args) {\n  return (...moreArgs) => fn(...args, ...moreArgs);\n}\n\nconst add = (a, b, c) => a + b + c;\nconst add5 = partial(add, 5);\nconsole.log(add5(3, 2)); \u002F\u002F 10\n\n\u002F\u002F Memoization\nfunction memoize(fn) {\n  const cache = new Map();\n  return (...args) => {\n    const key = JSON.stringify(args);\n    if (cache.has(key)) {\n      return cache.get(key);\n    }\n    const result = fn(...args);\n    cache.set(key, result);\n    return result;\n  };\n}\n\nconst fibonacci = memoize((n) => {\n  if (n \u003C= 1) return n;\n  return fibonacci(n - 1) + fibonacci(n - 2);\n});\n```\n\n### 3. Composition and Piping\n\n```javascript\n\u002F\u002F Function composition\nconst compose =\n  (...fns) =>\n  (x) =>\n    fns.reduceRight((acc, fn) => fn(acc), x);\n\nconst pipe =\n  (...fns) =>\n  (x) =>\n    fns.reduce((acc, fn) => fn(acc), x);\n\n\u002F\u002F Example usage\nconst addOne = (x) => x + 1;\nconst double = (x) => x * 2;\nconst square = (x) => x * x;\n\nconst composed = compose(square, double, addOne);\nconsole.log(composed(3)); \u002F\u002F ((3 + 1) * 2)^2 = 64\n\nconst piped = pipe(addOne, double, square);\nconsole.log(piped(3)); \u002F\u002F ((3 + 1) * 2)^2 = 64\n\n\u002F\u002F Practical example\nconst processUser = pipe(\n  (user) => ({ ...user, name: user.name.trim() }),\n  (user) => ({ ...user, email: user.email.toLowerCase() }),\n  (user) => ({ ...user, age: parseInt(user.age) }),\n);\n\nconst user = processUser({\n  name: \"  John  \",\n  email: \"JOHN@EXAMPLE.COM\",\n  age: \"30\",\n});\n```\n\n### 4. Pure Functions and Immutability\n\n```javascript\n\u002F\u002F Impure function (modifies input)\nfunction addItemImpure(cart, item) {\n  cart.items.push(item);\n  cart.total += item.price;\n  return cart;\n}\n\n\u002F\u002F Pure function (no side effects)\nfunction addItemPure(cart, item) {\n  return {\n    ...cart,\n    items: [...cart.items, item],\n    total: cart.total + item.price,\n  };\n}\n\n\u002F\u002F Immutable array operations\nconst numbers = [1, 2, 3, 4, 5];\n\n\u002F\u002F Add to array\nconst withSix = [...numbers, 6];\n\n\u002F\u002F Remove from array\nconst withoutThree = numbers.filter((n) => n !== 3);\n\n\u002F\u002F Update array element\nconst doubled = numbers.map((n) => (n === 3 ? n * 2 : n));\n\n\u002F\u002F Immutable object operations\nconst user = { name: \"John\", age: 30 };\n\n\u002F\u002F Update property\nconst olderUser = { ...user, age: 31 };\n\n\u002F\u002F Add property\nconst withEmail = { ...user, email: \"john@example.com\" };\n\n\u002F\u002F Remove property\nconst { age, ...withoutAge } = user;\n\n\u002F\u002F Deep cloning (simple approach)\nconst deepClone = (obj) => JSON.parse(JSON.stringify(obj));\n\n\u002F\u002F Better deep cloning\nconst structuredClone = (obj) => globalThis.structuredClone(obj);\n```\n\n## Modern Class Features\n\n```javascript\n\u002F\u002F Class syntax\nclass User {\n  \u002F\u002F Private fields\n  #password;\n\n  \u002F\u002F Public fields\n  id;\n  name;\n\n  \u002F\u002F Static field\n  static count = 0;\n\n  constructor(id, name, password) {\n    this.id = id;\n    this.name = name;\n    this.#password = password;\n    User.count++;\n  }\n\n  \u002F\u002F Public method\n  greet() {\n    return `Hello, ${this.name}`;\n  }\n\n  \u002F\u002F Private method\n  #hashPassword(password) {\n    return `hashed_${password}`;\n  }\n\n  \u002F\u002F Getter\n  get displayName() {\n    return this.name.toUpperCase();\n  }\n\n  \u002F\u002F Setter\n  set password(newPassword) {\n    this.#password = this.#hashPassword(newPassword);\n  }\n\n  \u002F\u002F Static method\n  static create(id, name, password) {\n    return new User(id, name, password);\n  }\n}\n\n\u002F\u002F Inheritance\nclass Admin extends User {\n  constructor(id, name, password, role) {\n    super(id, name, password);\n    this.role = role;\n  }\n\n  greet() {\n    return `${super.greet()}, I'm an admin`;\n  }\n}\n```\n\n## Modules (ES6)\n\n```javascript\n\u002F\u002F Exporting\n\u002F\u002F math.js\nexport const PI = 3.14159;\nexport function add(a, b) {\n  return a + b;\n}\nexport class Calculator {\n  \u002F\u002F ...\n}\n\n\u002F\u002F Default export\nexport default function multiply(a, b) {\n  return a * b;\n}\n\n\u002F\u002F Importing\n\u002F\u002F app.js\nimport multiply, { PI, add, Calculator } from \".\u002Fmath.js\";\n\n\u002F\u002F Rename imports\nimport { add as sum } from \".\u002Fmath.js\";\n\n\u002F\u002F Import all\nimport * as Math from \".\u002Fmath.js\";\n\n\u002F\u002F Dynamic imports\nconst module = await import(\".\u002Fmath.js\");\nconst { add } = await import(\".\u002Fmath.js\");\n\n\u002F\u002F Conditional loading\nif (condition) {\n  const module = await import(\".\u002Ffeature.js\");\n  module.init();\n}\n```\n\n## Iterators and Generators\n\n```javascript\n\u002F\u002F Custom iterator\nconst range = {\n  from: 1,\n  to: 5,\n\n  [Symbol.iterator]() {\n    return {\n      current: this.from,\n      last: this.to,\n\n      next() {\n        if (this.current \u003C= this.last) {\n          return { done: false, value: this.current++ };\n        } else {\n          return { done: true };\n        }\n      },\n    };\n  },\n};\n\nfor (const num of range) {\n  console.log(num); \u002F\u002F 1, 2, 3, 4, 5\n}\n\n\u002F\u002F Generator function\nfunction* rangeGenerator(from, to) {\n  for (let i = from; i \u003C= to; i++) {\n    yield i;\n  }\n}\n\nfor (const num of rangeGenerator(1, 5)) {\n  console.log(num);\n}\n\n\u002F\u002F Infinite generator\nfunction* fibonacci() {\n  let [prev, curr] = [0, 1];\n  while (true) {\n    yield curr;\n    [prev, curr] = [curr, prev + curr];\n  }\n}\n\n\u002F\u002F Async generator\nasync function* fetchPages(url) {\n  let page = 1;\n  while (true) {\n    const response = await fetch(`${url}?page=${page}`);\n    const data = await response.json();\n    if (data.length === 0) break;\n    yield data;\n    page++;\n  }\n}\n\nfor await (const page of fetchPages(\"\u002Fapi\u002Fusers\")) {\n  console.log(page);\n}\n```\n\n## Modern Operators\n\n```javascript\n\u002F\u002F Optional chaining\nconst user = { name: \"John\", address: { city: \"NYC\" } };\nconst city = user?.address?.city;\nconst zipCode = user?.address?.zipCode; \u002F\u002F undefined\n\n\u002F\u002F Function call\nconst result = obj.method?.();\n\n\u002F\u002F Array access\nconst first = arr?.[0];\n\n\u002F\u002F Nullish coalescing\nconst value = null ?? \"default\"; \u002F\u002F 'default'\nconst value = undefined ?? \"default\"; \u002F\u002F 'default'\nconst value = 0 ?? \"default\"; \u002F\u002F 0 (not 'default')\nconst value = \"\" ?? \"default\"; \u002F\u002F '' (not 'default')\n\n\u002F\u002F Logical assignment\nlet a = null;\na ??= \"default\"; \u002F\u002F a = 'default'\n\nlet b = 5;\nb ??= 10; \u002F\u002F b = 5 (unchanged)\n\nlet obj = { count: 0 };\nobj.count ||= 1; \u002F\u002F obj.count = 1\nobj.count &&= 2; \u002F\u002F obj.count = 2\n```\n\n## Performance Optimization\n\n```javascript\n\u002F\u002F Debounce\nfunction debounce(fn, delay) {\n  let timeoutId;\n  return (...args) => {\n    clearTimeout(timeoutId);\n    timeoutId = setTimeout(() => fn(...args), delay);\n  };\n}\n\nconst searchDebounced = debounce(search, 300);\n\n\u002F\u002F Throttle\nfunction throttle(fn, limit) {\n  let inThrottle;\n  return (...args) => {\n    if (!inThrottle) {\n      fn(...args);\n      inThrottle = true;\n      setTimeout(() => (inThrottle = false), limit);\n    }\n  };\n}\n\nconst scrollThrottled = throttle(handleScroll, 100);\n\n\u002F\u002F Lazy evaluation\nfunction* lazyMap(iterable, transform) {\n  for (const item of iterable) {\n    yield transform(item);\n  }\n}\n\n\u002F\u002F Use only what you need\nconst numbers = [1, 2, 3, 4, 5];\nconst doubled = lazyMap(numbers, (x) => x * 2);\nconst first = doubled.next().value; \u002F\u002F Only computes first value\n```\n\n## Best Practices\n\n1. **Use const by default**: Only use let when reassignment is needed\n2. **Prefer arrow functions**: Especially for callbacks\n3. **Use template literals**: Instead of string concatenation\n4. **Destructure objects and arrays**: For cleaner code\n5. **Use async\u002Fawait**: Instead of Promise chains\n6. **Avoid mutating data**: Use spread operator and array methods\n7. **Use optional chaining**: Prevent \"Cannot read property of undefined\"\n8. **Use nullish coalescing**: For default values\n9. **Prefer array methods**: Over traditional loops\n10. **Use modules**: For better code organization\n11. **Write pure functions**: Easier to test and reason about\n12. **Use meaningful variable names**: Self-documenting code\n13. **Keep functions small**: Single responsibility principle\n14. **Handle errors properly**: Use try\u002Fcatch with async\u002Fawait\n15. **Use strict mode**: `'use strict'` for better error catching\n\n## Common Pitfalls\n\n1. **this binding confusion**: Use arrow functions or bind()\n2. **Async\u002Fawait without error handling**: Always use try\u002Fcatch\n3. **Promise creation unnecessary**: Don't wrap already async functions\n4. **Mutation of objects**: Use spread operator or Object.assign()\n5. **Forgetting await**: Async functions return promises\n6. **Blocking event loop**: Avoid synchronous operations\n7. **Memory leaks**: Clean up event listeners and timers\n8. **Not handling promise rejections**: Use catch() or try\u002Fcatch\n\n## Resources\n\n- **MDN Web Docs**: https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\n- **JavaScript.info**: https:\u002F\u002Fjavascript.info\u002F\n- **You Don't Know JS**: https:\u002F\u002Fgithub.com\u002Fgetify\u002FYou-Dont-Know-JS\n- **Eloquent JavaScript**: https:\u002F\u002Feloquentjavascript.net\u002F\n- **ES6 Features**: http:\u002F\u002Fes6-features.org\u002F\n",{"name":5,"description":7},"main","2390b741d6daa7385cfb01fe351f64305cda49d5",".opencode\u002Fskills\u002Fmodern-javascript-patterns",2,"https:\u002F\u002Fgithub.com\u002Fdibstern\u002Fconduit","https:\u002F\u002Fgithub.com\u002Fdibstern","Software Engineer at Renowned, ex-Rome2Rio","2026-10-29 15:51:30",{"source":8,"skillName":5,"commands":58,"prompt":68,"zipAvailable":69},[59,62,65],{"tool":60,"command":61},"npx","npx skills add dibstern\u002Fconduit --skill modern-javascript-patterns",{"tool":63,"command":64},"bunx","bunx skills add dibstern\u002Fconduit --skill modern-javascript-patterns",{"tool":66,"command":67},"pnpm","pnpm dlx skills add dibstern\u002Fconduit --skill modern-javascript-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdibstern\u002Fconduit\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fmodern-javascript-patterns\u002FSKILL.md",true,[71],{"path":72,"resourceType":73,"resourceTypeDesc":74,"sizeBytes":75,"sourceHtmlUrl":76},".skillfish.json","REFERENCE","参考文档",266,"https:\u002F\u002Fgithub.com\u002Fdibstern\u002Fconduit\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fmodern-javascript-patterns\u002F.skillfish.json",[78,93,104,128,150,157],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":44},"01M6ENE9PDF6ZTQ0HN0M2NY8YN","release-notes","Drafts release notes. Fixture skill for conduit's recorded skill-loads-turn trace.","https:\u002F\u002Fgithub.com\u002Fdibstern\u002Fconduit\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Fclaude-sdk-traces\u002Fskill-loads-turn-skills\u002Frelease-notes\u002FSKILL.md",[],[85,86,87,88,89,90,91,92],"notes","release notes","release","conduit","trace","fixture skill","fixture","loads",{"skillNo":94,"name":95,"nameZh":6,"description":96,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":97,"categories":98,"keywords":99,"publishedAt":44},"01M6ENE72EV36TVDA9A00WHZWP","changelog-style","House style for changelog entries. Fixture skill for conduit's recorded skill-loads-turn trace.","https:\u002F\u002Fgithub.com\u002Fdibstern\u002Fconduit\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Fclaude-sdk-traces\u002Fskill-loads-turn-skills\u002Fchangelog-style\u002FSKILL.md",[],[100,101,102,88,89,90,103,91,92],"changelog","style","changelog style","entries",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":110,"publishedAt":44},"01M6ENE3R4WX66WR1SNJ98F89W","typescript-advanced-types","Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications. Use when implementing complex type logic, creating reusable type utilities, or ensuring compile-time type safety in TypeScript projects.","https:\u002F\u002Fgithub.com\u002Fdibstern\u002Fconduit\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Ftypescript-advanced-types\u002FSKILL.md",[],[111,112,113,114,115,116,117,118,119,33,38,120,121,122,123,124,125,126,41,127],"typescript","types","typescript advanced","typescript advanced types","type system","reusable","time","logic","type","template","utility","Type Safety","system","safe","compile","Safety","projects",{"skillNo":129,"name":130,"nameZh":6,"description":131,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":132,"categories":133,"keywords":139,"publishedAt":44},"01M6ENDWT23VWB5YJBXZFBRYRZ","sveltekit-svelte5-tailwind-skill","Comprehensive integration skill for building sites with SvelteKit 2, Svelte 5, and Tailwind CSS v4","https:\u002F\u002Fgithub.com\u002Fdibstern\u002Fconduit\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fsveltekit-svelte5-tailwind-skill\u002FSKILL.md",[134],{"categoryNo":135,"categoryName":136,"taxonomyType":137,"taxonomyTypeDesc":138},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[140,141,142,143,144,145,146,147,148,149],"sveltekit","Tailwind","sveltekit svelte5 tailwind skill","css","integration","only","svelte 5","Tailwind CSS","svelte","sites",{"skillNo":151,"name":152,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":155,"publishedAt":44},"01M6ENDSRWQ1XYJECFESE5R7EH","svelte5-inspect","https:\u002F\u002Fgithub.com\u002Fdibstern\u002Fconduit\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fsvelte5-inspect\u002FSKILL.md",[],[156],"svelte5 inspect",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":167,"publishedAt":44},"01M6ENDNVCSJ87AD76V5QTKG49","playwright-cli","Automates browser interactions for web testing, form filling, screenshots, and data extraction. Use when the user needs to navigate websites, interact with web pages, fill forms, take screenshots, test web applications, or extract information from web pages.","https:\u002F\u002Fgithub.com\u002Fdibstern\u002Fconduit\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fplaywright-cli\u002FSKILL.md",[163,166],{"categoryNo":164,"categoryName":165,"taxonomyType":137,"taxonomyTypeDesc":138},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":135,"categoryName":136,"taxonomyType":137,"taxonomyTypeDesc":138},[168,169,170,171,172,173,174,175,176,41,177,178,38,179,180,181,182,183,184,185],"playwright cli","playwright","cli","form","screenshots","test","web","browser","data","Bash","extract","take","test web","web testing","forms","pages","Data Extraction","testing"]