
agents 开源仓库实战指南modern-javascript-patterns 技能详解 ES6 现代 JavaScript 模式与函数式编程实践【免费下载链接】agentsMulti-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity项目地址: https://gitcode.com/GitHub_Trending/agents24/agents导读本篇文章围绕 agents 开源仓库中javascript-typescript插件所内置的modern-javascript-patterns技能展开系统梳理 ES6 的核心语法箭头函数、解构、展开/剩余运算符、模板字符串、增强对象字面量、异步编程Promise 与 async/await、函数式编程数组方法、高阶函数、组合与管道、纯函数与不可变性、现代类特性、ES 模块、迭代器与生成器、现代运算符以及性能优化防抖、节流、惰性求值的完整知识体系。读完本文你将掌握一套可直接用于重构遗留代码、实现数据转换管道与优化 JavaScript 应用性能的实战方案并能理解该技能在仓库中的组织方式与使用时机。技能概览这份技能讲什么modern-javascript-patterns是 plugins/javascript-typescript 插件下的四个技能之一其元数据SKILL.md声明了明确的定位名称modern-javascript-patterns描述掌握 ES6 特性包括 async/await、解构、展开运算符、箭头函数、Promise、模块、迭代器、生成器以及函数式编程模式用于编写干净、高效的 JavaScript 代码触发时机重构遗留代码、实现现代模式、优化 JavaScript 应用时使用。技能内部采用渐进式披露progressive disclosure组织顶层 SKILL.md 提供使用时机与 15 条最佳实践当导航层信息不足时读取 references/details.md 获取详细模式与完整代码示例再深入一层references/advanced-patterns.md 承载函数式编程、现代类、模块、迭代器/生成器、性能优化与常见陷阱的高级内容。这种三级结构正是仓库 docs/plugins.md 中描述的技能包设计理念——按需加载、节省上下文 token。何时使用该技能根据 SKILL.md该技能适用于以下八类场景将遗留 JavaScript 重构为现代语法实现函数式编程模式优化 JavaScript 性能编写可维护、可读的代码处理异步操作构建现代 Web 应用从回调迁移到 Promise / async-await实现数据转换管道。与同插件的其他技能形成互补关系javascript-proAgent见 agents/javascript-pro.md负责在现代 JS 与异步编程上提供专家能力其关注点ES6、事件循环、微任务队列、回调地狱治理与本技能高度呼应nodejs-backend-patterns技能负责服务端工程化javascript-testing-patterns技能负责测试typescript-advanced-types技能负责类型系统。本技能专注于语言本身的现代写法与函数式范式。15 条核心最佳实践SKILL.md 给出了浓缩的最佳实践清单这是全技能的行为准则具体如下默认使用const仅在需要重新赋值时使用let优先使用箭头函数尤其用于回调场景使用模板字符串替代字符串拼接解构对象与数组让代码更简洁使用 async/await替代 Promise 链避免修改数据使用展开运算符与数组方法使用可选链杜绝 Cannot read property of undefined使用空值合并运算符处理默认值优先使用数组方法替代传统循环使用模块更好地组织代码编写纯函数更易于测试与推理使用有意义的变量名让代码自文档化保持函数短小遵循单一职责原则正确处理错误async/await 配合 try/catch使用严格模式use strict以获得更好的错误捕获。这些实践并非孤立口号下文将从 ES6 核心语法到函数式编程逐条展开其背后的实现原理与代码形态。ES6 核心语法实战箭头函数语法糖与词法 thisreferences/details.md 展示了箭头函数从简单到复杂的五种形态// 传统函数 function add(a, b) { return a b; } // 箭头函数 const add (a, b) a b; // 单参数括号可省略 const double (x) x * 2; // 无参数 const getRandom () Math.random(); // 多语句需要花括号 const processUser (user) { const normalized user.name.toLowerCase(); return { ...user, name: normalized }; }; // 返回对象需要包裹圆括号 const createUser (name, age) ({ name, age });箭头函数最重要的行为差异是词法this绑定。下面的Counter类对比了三种写法class Counter { constructor() { this.count 0; } // 箭头函数保留 this 上下文类字段 increment () { this.count; }; // 传统函数在回调中丢失 this incrementTraditional() { setTimeout(function () { this.count; // this 是 undefined }, 1000); } // 箭头函数维持 this 指向 Counter 实例 incrementArrow() { setTimeout(() { this.count; // this 指向 Counter 实例 }, 1000); } }从源码结构可以推断该示例刻意演示了回调中function声明会丢失 this、而箭头函数捕获定义时的 this这一经典陷阱这也是 advanced-patterns.md 中this 绑定混淆陷阱的正面解法。解构对象与数组的取值艺术对象解构details.md支持重命名、默认值、嵌套、剩余运算符与函数参数解构const user { id: 1, name: John Doe, email: johnexample.com, address: { city: New York, country: USA }, }; // 基础解构 const { name, email } user; // 重命名变量 const { name: userName, email: userEmail } user; // 默认值 const { age 25 } user; // 嵌套解构 const { address: { city, country } } user; // 剩余运算符 const { id, ...userWithoutId } user; // 函数参数解构 function greet({ name, age 18 }) { console.log(Hello ${name}, you are ${age}); }数组解构details.md支持跳过元素、剩余、变量交换、函数返回值解构与默认值const numbers [1, 2, 3, 4, 5]; const [first, second] numbers; const [, , third] numbers; // 跳过前两个 const [head, ...tail] numbers; // 变量交换无需临时变量 let a 1, b 2; [a, b] [b, a]; // 函数返回值解构 function getCoordinates() { return [10, 20]; } const [x, y] getCoordinates(); // 默认值 const [one, two, three 0] [1, 2];展开与剩余运算符不可变操作的基础设施展开运算符details.md覆盖数组拼接、对象合并、函数参数、浅拷贝与不可变新增const arr1 [1, 2, 3]; const arr2 [4, 5, 6]; const combined [...arr1, ...arr2]; const defaults { theme: dark, lang: en }; const userPrefs { theme: light }; const settings { ...defaults, ...userPrefs }; // 后者覆盖前者 const numbers [1, 2, 3]; Math.max(...numbers); // 展开为独立参数 const copy [...arr1]; // 浅拷贝 const objCopy { ...user }; const newArr [...arr1, 4, 5]; // 不可变追加 const newObj { ...user, age: 30 };剩余参数details.md用于收集参数与剥离属性function sum(...numbers) { return numbers.reduce((total, num) total num, 0); } function greet(greeting, ...names) { return ${greeting} ${names.join(, )}; } const { id, ...userData } user; // 对象剩余 const [first, ...rest] [1, 2, 3, 4, 5]; // 数组剩余模板字符串从拼接走向标签模板模板字符串details.md解决了拼接可读性、多行字符串与表达式求值问题并支持高级的标签模板tagged templateconst name John; const greeting Hello, ${name}!; // 多行字符串 const html div h1${title}/h1 p${content}/p /div ; // 表达式求值 const price 19.99; const total Total: $${(price * 1.2).toFixed(2)}; // 标签模板自定义插值渲染 function highlight(strings, ...values) { return strings.reduce((result, str, i) { const value values[i] || ; return result str mark${value}/mark; }, ); } const html highlightName: ${name}, Age: ${age}; // 输出: Name: markJohn/mark, Age: mark30/mark增强对象字面量简写、计算属性与动态构建details.md 展示了属性简写、方法简写、计算属性名以及用 reduce 动态构造对象const name John; const age 30; // 属性简写 const user { name, age }; // 方法简写 const calculator { add(a, b) { return a b; }, subtract(a, b) { return a - b; }, }; // 计算属性名 const field email; const user { name: John, [field]: johnexample.com, [get${field.charAt(0).toUpperCase()}${field.slice(1)}]() { return this[field]; }, }; // 动态属性创建reduce 展开 const createUser (name, ...props) { return props.reduce( (user, [key, value]) ({ ...user, [key]: value }), { name }, ); };异步编程模式Promise创建、链式调用与四大组合器Promise 的创建与链式调用details.mdconst fetchUser (id) { return new Promise((resolve, reject) { setTimeout(() { if (id 0) resolve({ id, name: John }); else reject(new Error(Invalid ID)); }, 1000); }); }; fetchUser(1) .then((user) console.log(user)) .catch((error) console.error(error)) .finally(() console.log(Done)); // 链式调用 fetchUser(1) .then((user) fetchUserPosts(user.id)) .then((posts) processPosts(posts)) .then((result) console.log(result)) .catch((error) console.error(error));四个 Promise 组合器的语义差异details.mdPromise.all等待全部成功任一失败即整体失败Promise.allSettled等待全部结束无论成败适合批量任务逐项处理statusPromise.race返回最先完成无论成败的结果Promise.any返回第一个成功的结果全部失败才拒绝。Promise.all(promises) .then((users) console.log(users)) .catch((error) console.error(At least one failed:, error)); Promise.allSettled(promises).then((results) { results.forEach((result) { if (result.status fulfilled) { console.log(Success:, result.value); } else { console.log(Error:, result.reason); } }); }); Promise.race(promises).then((winner) console.log(First:, winner)); Promise.any(promises).then((first) console.log(First success:, first));async/await从基础到高级模式基础用法与错误处理details.md——async 函数总是返回 Promisetry/catch 包裹 await顺序与并行执行的取舍async function fetchUser(id) { const response await fetch(/api/users/${id}); const user await response.json(); return user; } async function getUserData(id) { try { const user await fetchUser(id); const posts await fetchUserPosts(user.id); return { user, posts }; } catch (error) { console.error(Error fetching data:, error); throw error; } } // 顺序执行逐个等待 async function sequential() { const user1 await fetchUser(1); const user2 await fetchUser(2); return [user1, user2]; } // 并行执行Promise.all 同时发起 async function parallel() { const [user1, user2] await Promise.all([fetchUser(1), fetchUser(2)]); return [user1, user2]; }高级模式details.md覆盖 Async IIFE、异步迭代、顶层 awaitES2022、重试逻辑与超时包装// Async IIFE脚本顶层直接 await (async () { const result await someAsyncOperation(); console.log(result); })(); // 异步迭代 async function processUsers(userIds) { for (const id of userIds) { const user await fetchUser(id); await processUser(user); } } // 顶层 awaitES2022 const config await fetch(/config.json).then((r) r.json()); // 重试逻辑指数退避 async function fetchWithRetry(url, retries 3) { for (let i 0; i retries; i) { try { return await fetch(url); } catch (error) { if (i retries - 1) throw error; await new Promise((resolve) setTimeout(resolve, 1000 * (i 1))); } } } // 超时包装race 竞速 async function withTimeout(promise, ms) { const timeout new Promise((_, reject) setTimeout(() reject(new Error(Timeout)), ms), ); return Promise.race([promise, timeout]); }函数式编程模式函数式编程的核心是纯函数、不可变性与可组合的转换。这一部分在 details.md 中总览完整示例沉淀在 advanced-patterns.md。数组方法全家桶map/filter/reduce的经典组合与链式调用advanced-patterns.mdconst users [ { id: 1, name: John, age: 30, active: true }, { id: 2, name: Jane, age: 25, active: false }, { id: 3, name: Bob, age: 35, active: true }, ]; const names users.map((user) user.name); const activeUsers users.filter((user) user.active); const totalAge users.reduce((sum, user) sum user.age, 0); // 按属性分组 const byActive users.reduce((groups, user) { const key user.active ? active : inactive; return { ...groups, [key]: [...(groups[key] || []), user] }; }, {}); // 链式管道 const result users .filter((user) user.active) .map((user) user.name) .sort() .join(, );补充的高级方法advanced-patterns.mdfind首个匹配、findIndex首个匹配索引、some至少一个、every全部满足、flatMap映射后拍平一层、Array.from从可迭代对象/类数组构造支持 mapFn、Array.of从参数构造const user users.find((u) u.id 2); const hasActive users.some((u) u.active); const allAdults users.every((u) u.age 18); const allTags userTags.flatMap((u) u.tags); const chars Array.from(hello); const numbers Array.from({ length: 5 }, (_, i) i 1); const arr Array.of(1, 2, 3);高阶函数接收与返回函数的函数手写forEach/map/filter展示高阶函数的本质advanced-patterns.mdfunction forEach(array, callback) { for (let i 0; i array.length; i) { callback(array[i], i, array); } } function map(array, transform) { const result []; for (const item of array) { result.push(transform(item)); } return result; } function filter(array, predicate) { const result []; for (const item of array) { if (predicate(item)) result.push(item); } return result; }柯里化、偏函数与记忆化advanced-patterns.md// 柯里化逐步固定参数 const multiply (a) (b) a * b; const double multiply(2); const triple multiply(3); // 偏函数应用 function partial(fn, ...args) { return (...moreArgs) fn(...args, ...moreArgs); } const add5 partial((a, b, c) a b c, 5); console.log(add5(3, 2)); // 10 // 记忆化缓存计算结果Map 作为缓存 function memoize(fn) { const cache new Map(); return (...args) { const key JSON.stringify(args); if (cache.has(key)) return cache.get(key); const result fn(...args); cache.set(key, result); return result; }; } const fibonacci memoize((n) { if (n 1) return n; return fibonacci(n - 1) fibonacci(n - 2); });组合与管道compose / pipeadvanced-patterns.md 给出两个核心工具compose右到左reduceRight与pipe左到右reduce二者数学上等价const compose (...fns) (x) fns.reduceRight((acc, fn) fn(acc), x); const pipe (...fns) (x) fns.reduce((acc, fn) fn(acc), x); const addOne (x) x 1; const double (x) x * 2; const square (x) x * x; const composed compose(square, double, addOne); const piped pipe(addOne, double, square); // 两者都输出 64((3 1) * 2)^2 // 实战用户数据清洗管道 const processUser pipe( (user) ({ ...user, name: user.name.trim() }), (user) ({ ...user, email: user.email.toLowerCase() }), (user) ({ ...user, age: parseInt(user.age) }), );纯函数与不可变性advanced-patterns.md 通过购物车案例对比了污染输入的不纯实现与返回新对象的纯实现// 不纯直接修改输入 function addItemImpure(cart, item) { cart.items.push(item); cart.total item.price; return cart; } // 纯返回新对象无副作用 function addItemPure(cart, item) { return { ...cart, items: [...cart.items, item], total: cart.total item.price, }; } // 不可变数组操作 const withSix [...numbers, 6]; const withoutThree numbers.filter((n) n ! 3); const doubled numbers.map((n) (n 3 ? n * 2 : n)); // 不可变对象操作 const olderUser { ...user, age: 31 }; const { age, ...withoutAge } user; // 删除属性 // 深拷贝结构化克隆现代运行时推荐 const deepClone (obj) globalThis.structuredClone(obj);注意globalThis.structuredClone的可用性取决于运行环境传统环境可退化为JSON.parse(JSON.stringify(obj))但后者无法处理undefined、函数、Date等特殊值。现代类特性ES2022advanced-patterns.md 完整演示了私有字段#field、公共字段、静态字段/方法、私有方法、getter/setter 与继承class User { #password; // 私有字段 id; // 公共字段 name; static count 0; // 静态字段 constructor(id, name, password) { this.id id; this.name name; this.#password password; User.count; } greet() { return Hello, ${this.name}; } #hashPassword(password) { return hashed_${password}; } // 私有方法 get displayName() { return this.name.toUpperCase(); } set password(newPassword) { this.#password this.#hashPassword(newPassword); } static create(id, name, password) { return new User(id, name, password); } } // 继承 super 调用 class Admin extends User { constructor(id, name, password, role) { super(id, name, password); this.role role; } greet() { return ${super.greet()}, Im an admin; } }私有字段#前缀是 ES2022 真正的语言级封装外部无法直接访问#password只能通过 getter/setter 间接操作——这为封装敏感数据 校验入口提供了比闭包更直观的语法。ES6 模块系统基础导入导出details.md// 命名导出 export const PI 3.14159; export function add(a, b) { return a b; } // 默认导出 export default function multiply(a, b) { return a * b; } // 导入 import multiply, { PI, add } from ./math.js; // 动态导入代码分割 const { add } await import(./math.js);高级用法advanced-patterns.md重命名导入、命名空间导入与条件加载import { add as sum } from ./math.js; import * as Math from ./math.js; // 条件加载按需初始化 if (condition) { const module await import(./feature.js); module.init(); }动态导入是代码分割code splitting的基础只有实际需要时才拉取对应 chunk从而缩小首屏包体——这与javascript-proAgent 中为浏览器代码考虑 bundle size的关注点agents/javascript-pro.md一脉相承。迭代器与生成器自定义迭代器、生成器、无限生成器与异步生成器advanced-patterns.md// 自定义迭代器Symbol.iterator 协议 const range { from: 1, to: 5, [Symbol.iterator]() { return { current: this.from, last: this.to, next() { if (this.current this.last) { return { done: false, value: this.current }; } return { done: true }; }, }; }, }; for (const num of range) console.log(num); // 1 2 3 4 5 // 生成器函数yield 惰性产出 function* rangeGenerator(from, to) { for (let i from; i to; i) yield i; } // 无限生成器斐波那契惰性按需取 function* fibonacci() { let [prev, curr] [0, 1]; while (true) { yield curr; [prev, curr] [curr, prev curr]; } } // 异步生成器分页拉取 async function* fetchPages(url) { let page 1; while (true) { const response await fetch(${url}?page${page}); const data await response.json(); if (data.length 0) break; yield data; page; } } for await (const page of fetchPages(/api/users)) { console.log(page); }生成器的核心价值是惰性求值无限序列不会一次性占用内存分页数据按需逐页拉取。for await...of则是异步生成器的消费端配套语法。现代运算符可选链、空值合并与逻辑赋值details.md 与 advanced-patterns.md 共同覆盖三组现代运算符// 可选链安全访问属性 / 方法 / 数组下标 const city user?.address?.city; const result obj.method?.(); const first arr?.[0]; // 空值合并仅在 null/undefined 时取默认值0 和 保留 const value null ?? default; // default const zero 0 ?? default; // 0 const empty ?? default; // // 逻辑赋值 a ?? default; // 仅在 null/undefined 时赋值 obj.count || 1; // 仅在 falsy 时赋值 obj.count 2; // 仅在 truthy 时赋值关键区分??只对null/undefined生效而||对所有 falsy 值含0、、NaN生效。需要保留合法假值的场景必须用??否则默认值会错误覆盖0或空字符串——这是该技能反复强调的边界。性能优化防抖、节流与惰性求值advanced-patterns.md 提供了三个高频性能工具// 防抖停止触发 delay 毫秒后才执行适用于搜索输入 function debounce(fn, delay) { let timeoutId; return (...args) { clearTimeout(timeoutId); timeoutId setTimeout(() fn(...args), delay); }; } const searchDebounced debounce(search, 300); // 节流limit 毫秒内最多执行一次适用于滚动/拖拽 function throttle(fn, limit) { let inThrottle; return (...args) { if (!inThrottle) { fn(...args); inThrottle true; setTimeout(() (inThrottle false), limit); } }; } const scrollThrottled throttle(handleScroll, 100); // 惰性求值生成器按需计算 function* lazyMap(iterable, transform) { for (const item of iterable) { yield transform(item); } } const doubled lazyMap([1, 2, 3, 4, 5], (x) x * 2); const first doubled.next().value; // 只计算第一个值防抖与节流都利用闭包保存状态timeoutId/inThrottle这是高阶函数 闭包的典型工程应用。常见陷阱清单advanced-patterns.md 汇总了 8 类高频陷阱供自查this 绑定混淆用箭头函数或bind()解决async/await 无错误处理始终配合 try/catch不必要的 Promise 包装不要包裹本已返回 Promise 的函数即Promise 反模式对应 SKILL.md 中提到的 promise anti-patterns对象被修改用展开运算符或Object.assign()忘记 awaitasync 函数返回的是 Promise阻塞事件循环避免同步长任务内存泄漏及时清理事件监听器与定时器未处理的 Promise 拒绝用catch()或 try/catch。技能在仓库中的定位与使用方式本技能隶属于javascript-typescript插件。根据 docs/plugins.md 的说明安装方式如下/plugin install javascript-typescript该插件还会装载javascript-pro、typescript-pro两个 Agent见 agents/javascript-pro.md 与 agents/typescript-pro.md以及typescript-scaffold命令和javascript-testing-patterns、nodejs-backend-patterns、typescript-advanced-types、modern-javascript-patterns四个技能。若只想单独引入本技能而不装整个插件可通过 Agent Skills 安装器读取plugins/*/skills/目录详见 docs/harnesses.md。在实际使用中本文介绍的语法模式与函数式工具可以直接落地为遗留代码重构把回调嵌套改写为 async/await把var拼接改写为const 模板字符串数据转换管道用pipe 纯函数串起清洗、校验、格式化步骤性能优化用防抖/节流治理高频事件用生成器实现惰性分页与无限序列代码质量遵循 15 条最佳实践规避 8 类常见陷阱让代码可读、可测、可维护。小结modern-javascript-patterns技能以 SKILL.md 为导航骨架以 references/details.md 与 references/advanced-patterns.md 为深度载体构成了从 ES6 语法、异步模式、函数式编程到性能优化的完整知识闭环。对于正在重构遗留代码或希望以现代范式编写 JavaScript 的开发者这套三级文档既提供了即取即用的代码模板也给出了背后的设计动机与边界条件是一份值得反复查阅的实战手册。【免费下载链接】agentsMulti-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity项目地址: https://gitcode.com/GitHub_Trending/agents24/agents创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考