[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M70NTJ02W4AME5TSX73QCYRF":3,"skill-same:01M70NTJ02W4AME5TSX73QCYRF":73},{"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":54,"ownerHtmlUrl":55,"ownerBlogUrl":56,"ownerDescription":57,"updatedAt":58,"install":59,"resources":72},"01M70NTJ02W4AME5TSX73QCYRF","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.","shengdabai\u002FTony-Claude-Code-Skills","shengdabai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F116417419?v=4","01M70F6D2WY5PQV5A92BKYJQEW","Tony Sheng","01M70F6D3GAAAYZ5H4CC1G8VXM",3,"MIT","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fwshobson-agents\u002Fplugins\u002Fjavascript-typescript\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],"patterns","javascript","modern javascript patterns","functional programming","await","master","features","legacy code","refactoring","operators","functional","code","when","writing","clean","implementing","refactoring legacy code","es6","promises","modules","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```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```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```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 { address: { city, country } } = 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```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, 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```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```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((user, [key, value]) => ({\n    ...user,\n    [key]: value\n  }), { name });\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```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```javascript\n\u002F\u002F Promise.all - Wait for all promises\nconst promises = [\n  fetchUser(1),\n  fetchUser(2),\n  fetchUser(3)\n];\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)\n  .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```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([\n    fetchUser(1),\n    fetchUser(2)\n  ]);\n  return [user1, user2];\n}\n```\n\n**Advanced Patterns:**\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```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```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```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```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 = (...fns) => x =>\n  fns.reduceRight((acc, fn) => fn(acc), x);\n\nconst pipe = (...fns) => 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```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```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```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 { address: { city, country } } = 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```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, 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```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```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((user, [key, value]) => ({\n    ...user,\n    [key]: value\n  }), { name });\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```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```javascript\n\u002F\u002F Promise.all - Wait for all promises\nconst promises = [\n  fetchUser(1),\n  fetchUser(2),\n  fetchUser(3)\n];\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)\n  .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```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([\n    fetchUser(1),\n    fetchUser(2)\n  ]);\n  return [user1, user2];\n}\n```\n\n**Advanced Patterns:**\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```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```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```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```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 = (...fns) => x =>\n  fns.reduceRight((acc, fn) => fn(acc), x);\n\nconst pipe = (...fns) => 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","7850740bd837adb32f0a109ab2af82482196c6f2","skills\u002Fwshobson-agents\u002Fplugins\u002Fjavascript-typescript\u002Fskills\u002Fmodern-javascript-patterns",1,"https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills","https:\u002F\u002Fzturnsgo.com","https:\u002F\u002Fgithub.com\u002Fshengdabai","https:\u002F\u002Fzturnsgo.com\u002F","AI × education creator — producer, not consumer. Taught 6,000+ learners; shipping learning tools & daily essays with Claude Code, practicing @xiaolai's way 🥋","2026-11-01 21:28:23",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add shengdabai\u002FTony-Claude-Code-Skills --skill modern-javascript-patterns",{"tool":65,"command":66},"bunx","bunx skills add shengdabai\u002FTony-Claude-Code-Skills --skill modern-javascript-patterns",{"tool":68,"command":69},"pnpm","pnpm dlx skills add shengdabai\u002FTony-Claude-Code-Skills --skill modern-javascript-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fwshobson-agents\u002Fplugins\u002Fjavascript-typescript\u002Fskills\u002Fmodern-javascript-patterns\u002FSKILL.md",true,[],[74,92,121,147,169,189],{"skillNo":75,"name":76,"nameZh":6,"description":77,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":85,"publishedAt":44},"01M70P17DAD4C1C47NPH6A96EM","xiaolai-methodology","以李笑来(Li Xiaolai)的思考方式、方法论与表达风格,为用户做全方位 1-on-1 教练指导,覆盖创业、赚钱、投资、学习、自学、读书写作、用 AI、以及人生心态与自我管理。当用户提到 \"李笑来\"、\"笑来\"、\"笑来老师\"、\"扮演李笑来\"、\"找笑来聊聊\"、\"笑来怎么看\"、\"xiaolai\"、\"把时间当作朋友\"、\"通往财富自由之路\"、\"定投改变命运\"、\"韭菜的自我修养\"、\"自学是门手艺\"、\"让时间陪你慢慢变富\"、\"七年就是一辈子\"、\"元认知\"、\"活在未来\"、\"复利\u002F长期主义\"、\"践行\"、\"痴迷改进\"、\"个人商业模式\u002F出售时间\"、\"睡后收入\"、\"定投\"、\"财富自由\"、\"操作系统升级\"、\"最少必要知识\"、\"北极星提示词\"、\"用 AI 该怎么学\u002F思考\" 等任一触发词,或当用户带着关于创业\u002F赚钱\u002F投资\u002F学习\u002F职业\u002F重大人生决策的困惑、希望被人用笑来式的「逻辑 + 大白话 + 类比 + 重新定义 + 践行导向」来点醒和指导时,自动进入李笑来教练模式。","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fxiaolai-methodology\u002FSKILL.md",[80],{"categoryNo":81,"categoryName":82,"taxonomyType":83,"taxonomyTypeDesc":84},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",[86,87,88,89,90,37,91],"methodology","xiaolai","xiaolai methodology","朋友","投资","收入",{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":102,"publishedAt":44},"01M70P13NB9YP7ACJR1S861CDS","zread","Produce and consume a wiki-style knowledge base for a code repository via the `zread` CLI and its on-disk output under `.\u002F.zread\u002Fwiki\u002F`. Use this skill whenever the user wants to understand, onboard onto, explore, summarize, map, or get an overview of an unfamiliar codebase; asks for architecture docs, a project wiki, a repo walkthrough, module\u002Fpackage explanations, or \"what does this repo do\"; wants to generate, regenerate, resume, browse, or serve code documentation locally; or mentions zread \u002F zread.ai directly. Also use it proactively before diving into a large unknown repo — if `.\u002F.zread\u002Fwiki\u002Fcurrent` exists, read the generated pages instead of crawling source file-by-file; if it doesn't, consider offering to run `zread generate`. The trigger is the intent (understand a codebase through generated docs), not the literal word \"zread\".","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fzread\u002FSKILL.md",[98,101],{"categoryNo":99,"categoryName":100,"taxonomyType":83,"taxonomyTypeDesc":84},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[94,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,35,119,120],"knowledge","wiki","explore","walkthrough","project","get","knowledge base","run","generate","intent","cli","map","documentation","project wiki","disk","architecture","unknown","generated",{"skillNo":122,"name":123,"nameZh":6,"description":124,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":131,"publishedAt":44},"01M70P10S4SWMZQ8BJAFBFDRW3","youtube","Launch the YouTube Creator Agent to auto-generate videos.\nUse when: user types \u002Fyoutube, wants to create YouTube videos,\ngenerate video content, or upload to YouTube.\nKeywords: youtube, video, 视频, 创作视频, 发布视频","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube\u002FSKILL.md",[127,128],{"categoryNo":99,"categoryName":100,"taxonomyType":83,"taxonomyTypeDesc":84},{"categoryNo":129,"categoryName":130,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000036","内容创作者",[123,132,133,134,135,136,137,138,111,139,140,141,36,142,143,144,145,146],"user","content","视频","creator","generate video","videos","launch","video content","create","upload","use","auto","types","Video","创作",{"skillNo":148,"name":149,"nameZh":6,"description":150,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":151,"categories":152,"keywords":154,"publishedAt":44},"01M70P0YE95D8BACZCGV8BK90K","youtube-script-sync","Sync, update, or optimize Tony's GetNote knowledge base `Youtube视频逐字稿` by turning each parent recording or first-person idea note into an idempotent child note containing a directly recordable YouTube long-video or Shorts script. Use when the user says “更新\u002F同步\u002F优化 Youtube视频逐字稿知识库”, or says “更新\u002F同步\u002F优化该知识库” while this knowledge base is the active context.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube-script-sync\u002FSKILL.md",[153],{"categoryNo":99,"categoryName":100,"taxonomyType":83,"taxonomyTypeDesc":84},[155,156,123,157,158,145,159,160,161,162,163,164,165,166,109,167,36,142,103,168],"sync","script","youtube script sync","recording","shorts","first","base","person","update","active","child","optimize","idempotent","long",{"skillNo":170,"name":171,"nameZh":6,"description":172,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":173,"categories":174,"keywords":179,"publishedAt":44},"01M70P0WMV5XT0EEC0N445PW07","writing-skills","How to write SKILL.md files that trigger reliably and teach effectively. Use when creating, improving, or reviewing Claude Code skills.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fxiaolai\u002Fnlpm\u002Fskills\u002Fnlpm\u002Fwriting-skills\u002FSKILL.md",[175,176,177,178],{"categoryNo":81,"categoryName":82,"taxonomyType":83,"taxonomyTypeDesc":84},{"categoryNo":99,"categoryName":100,"taxonomyType":83,"taxonomyTypeDesc":84},{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":129,"categoryName":130,"taxonomyType":21,"taxonomyTypeDesc":22},[180,37,181,182,183,184,35,36,142,185,186,187,188],"writing skills","how","teach","write skill","write","claude code skills","files","how to","trigger",{"skillNo":190,"name":191,"nameZh":6,"description":192,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":193,"categories":194,"keywords":197,"publishedAt":44},"01M70P0SJFR4YVJQBGMHKGSKXT","writing-rules","How to write .claude\u002Frules\u002F files that Claude actually follows. Use when creating, improving, or reviewing project rules.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fxiaolai\u002Fnlpm\u002Fskills\u002Fnlpm\u002Fwriting-rules\u002FSKILL.md",[195,196],{"categoryNo":81,"categoryName":82,"taxonomyType":83,"taxonomyTypeDesc":84},{"categoryNo":129,"categoryName":130,"taxonomyType":21,"taxonomyTypeDesc":22},[198,37,199,107,200,186,36,181,184,142,187],"Rules","writing rules","project rules"]