
es-toolkit 兼容 Lodash 的 wrap 函数函数包装与高阶封装的完整实战指南【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit导读wrap是 es-toolkit 在 compatLodash 兼容 模块中提供的函数包装工具它允许你创建一个新函数将原始值或函数作为第一个参数传给自定义的包装函数wrapper从而在原逻辑前后附加日志、性能测量、HTML 渲染等额外行为。本文以 日文版兼容文档 为核心骨架结合 wrap 源码实现 与 wrap 测试用例带你掌握wrap的调用签名、三种典型用法包装函数、包装非函数值、复杂包装、参数/返回值语义以及其底层this绑定与空值回退等实现细节并给出与原生闭包方案的取舍建议。一、wrap是什么签名与定位wrap(value, wrapper)会创建一个包装后的新函数。其 TypeScript 签名如下const wrappedFunc wrap(value, wrapper);完整的类型签名见 wrap.ts 源码export function wrapT, U, V( value: T, wrapper: (value: T, ...args: U[]) V ): (...args: U[]) V;第一个参数value被包装的值或函数类型T第二个参数wrapper包装函数它接收原始值作为第一个参数并应用附加逻辑类型(value: T, ...args: U[]) V返回值一个应用了包装函数的新函数(...args: U[]) V。从 es-toolkit 源码结构看wrap属于 compatLodash 兼容层与_.wrap行为对齐通过 compat 模块入口 导出export { wrap } from ./function/wrap.ts;使用时可从es-toolkit/compat导入import { wrap } from es-toolkit/compat;使用建议优先考虑高阶函数原文档在开头给出了重要警示wrap只是简单地将函数包装起来在大多数场景下使用更简洁的高阶函数higher-order function或闭包closure反而更清晰、更快速。它主要面向从 lodash 迁移到 es-toolkit 时保持行为一致的兼容场景。如果你正在编写新代码请优先考虑直接定义闭包或高阶函数只有需要与 Lodash 代码库保持等价语义时才选用wrap。二、核心用法一包装函数以附加额外逻辑当你希望对一个已有函数追加执行前/执行后的额外行为时可以把该函数作为value传入包装函数将收到原始函数作为第一个参数。示例为函数添加日志功能import { wrap } from es-toolkit/compat; // 包装函数以添加日志功能 const greet (name: string) Hi, ${name}; const loggedGreet wrap(greet, (originalFunc, name) { const result originalFunc(name); console.log([LOG] ${result}); return result; }); loggedGreet(Alice); // 控制台输出 [LOG] Hi, Alice 并返回 Hi, Alice在这个例子中originalFunc就是被包装的greet函数包装函数在其调用前后插入了日志逻辑同时保留原始返回值。示例为函数添加性能测量原文档给出了更复杂的包装示例——在执行前后记录耗时import { wrap } from es-toolkit/compat; const add (a: number, b: number) a b; // 创建带性能测量功能的函数 const timedAdd wrap(add, (originalAdd, a, b) { const start Date.now(); const result originalAdd(a, b); const end Date.now(); console.log(执行时间: ${end - start}ms); return result; }); timedAdd(3, 7); // 控制台输出执行时间并返回 10注意这里add是多参数函数a、b调用timedAdd(3, 7)时除原始函数外的其余参数3、7会依次传给包装函数——这正是wrapper: (value: T, ...args: U[]) V中...args的语义。三、核心用法二包装非函数值wrap不仅支持函数也支持包装任意值。此时该值会作为包装函数的第一个参数被传入返回的函数则用于接收后续参数。示例用 HTML 标签包裹字符串import { wrap } from es-toolkit/compat; // 创建将字符串包裹进 HTML 标签的函数 const htmlWrapper wrap(Hello World, (text, tag) ${tag}${text}/${tag}); console.log(htmlWrapper(h1)); // h1Hello World/h1这里value Hello World被作为text传入包装函数调用htmlWrapper(h1)时h1作为第二个参数tag传入。示例将数字用于计算import { wrap } from es-toolkit/compat; // 创建将数字用于计算的函数 const calculate wrap(10, (baseValue, multiplier) baseValue * multiplier); console.log(calculate(5)); // 5010作为基数baseValue被固定下来calculate(5)中5作为乘数传入得到10 * 5 50。这种值 参数的组合方式本质上是把一部分状态提前固化在闭包中。四、参数与返回值详解原文档对参数与返回值给出了明确说明这里结合源码进一步展开参数valueT要包装的值或函数。源码将其作为包装函数的第一个参数固定传入见 wrap.tswrapFn.apply(this, [value, ...args])。wrapper(value: T, ...args: U[]) V)接收原始值作为第一个参数并应用附加逻辑的函数。调用wrapped(...args)时...args会紧随value之后传递给wrapper。返回值(...args: U[]) V应用了包装函数的新函数。每次调用该新函数时都会把固定的value与本次调用的参数合并再调用wrapper。源码中的两个关键实现细节this绑定透传源码中返回的函数声明为function (this: unknown, ...args: any[])并通过wrapFn.apply(this, [value, ...args])调用包装函数见 wrap.ts。这意味着包装函数内的this与调用者保持一致原文档与测试用例均验证了这一行为详见下文第五节的this绑定测试。空值回退到 identity源码使用isFunction(wrapper)实现见 isFunction.ts即typeof value function判断包装函数是否有效若wrapper为null、undefined等非函数值则回退到identity见 identity.ts原样返回输入。这一设计与 Lodash 中wrapper 为空时使用_.identity的语义保持一致兼容性测试也专门覆盖了该分支。五、源码与测试验证从测试用例理解行为边界wrap.spec.ts 使用 Vitest 编写共 5 组用例完整覆盖了wrap的行为边界可作为理解该函数语义的权威依据创建包装函数wrap(escape, (func, text) ...)对 HTML 转义函数escape进行包装验证输出为pfred, barney amp; pebbles/p即包装逻辑在原始函数之外生效。wrapper 参数顺序通过slice.call(arguments)捕获包装函数收到的全部参数断言结果为[noop, 1, 2, 3]——原始函数noop永远排在第一随后才是调用时传入的参数。wrapper 为空值时使用 identity对null、undefined等值wrap(a, value)返回的函数直接透传参数期望结果与stubA一致印证了源码中的 identity 回退逻辑。this绑定wrap(escape, function (func) { return p func(this.text) /p; })挂载到对象{ p, text: fred, barney pebbles }上后object.p()能正确读取this.text验证了this透传行为。原始值包装wrap(value, v p v /p)直接返回pvalue/p验证了包装非函数值的能力。这些测试与 日文版参考文档 中的示例互为印证也说明wrap的设计目标是与 Lodash 兼容语义完全对齐。六、实战场景小结与最佳实践wrap在 es-toolkit 中的典型应用场景包括横切关注点注入为既有函数统一附加日志、计时、鉴权等逻辑且无需修改原函数实现渲染/序列化扩展将基础值字符串、数字、对象包装成带格式的输出如 HTML 标签、模板结构Lodash 代码迁移将_.wrap调用平滑迁移到es-toolkit/compat保持行为不变。需要再次强调的是原文档的核心建议若编写全新代码优先使用更快的现代闭包或直接函数定义例如// 用闭包替代 wrap 的等价写法 const loggedGreet (name: string) { const result Hi, ${name}; console.log([LOG] ${result}); return result; };只有在需要与 Lodash 语义严格兼容、或需要以值 动态包装函数方式抽象逻辑时才选择wrap。把握这一边界就能在代码可读性、性能与兼容性之间做出正确取舍。延伸阅读compat 模块总览了解 es-toolkit 的 Lodash 兼容层设计wrap 英文参考文档wrap的英文原版说明wrap 源码核心实现约 34 行wrap 测试用例行为边界验证compat 模块入口wrap的导出位置【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考