
es-toolkit compat 的 over 函数详解用一组谓词同时对多组数据执行并行计算【免费下载链接】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本文围绕 es-toolkit 的 Lodash 兼容层compat中的over函数展开它如何把一组函数或属性访问器“编译”成一个并行执行器、其内部的 iteratee 简写机制如何工作以及为什么官方文档明确建议优先使用原生Array.map替代该函数。读完本文你将掌握over的全部用法函数、属性名、属性-值对、部分对象匹配、嵌套路径理解其在 over.ts 中的实现细节与 iteratee.ts 简写转换规则并能根据性能权衡做出合理的选型决策。一、over 是做什么的over创建的是一个“多路并行调用器”给定一组谓词函数、属性名、匹配对象等它会返回一个新函数调用该新函数时同一组实参会被依次传给每一个谓词所有结果按序收集成数组返回。它适合“同一份数据需要同时做多项计算”的场景。官方文档位于 docs/ja/compat/reference/util/over.md函数签名如下const multiCall over(funcs);需要注意官方文档在开头即给出了明确的性能警示原文以 warning 标注该over函数在把函数映射成数组的过程中会产生额外开销。建议改用更快、更现代的原生数组map方法。这一点会在第六节结合源码做进一步展开。二、基本用法over(...iteratees)over接受可变参数支持两种等价写法传一个数组或把谓词作为多个独立参数传入。import { over } from es-toolkit/compat; // 数学函数组合 const mathOperations over([Math.max, Math.min]); mathOperations(1, 2, 3, 4); // [4, 1] // 也可以直接以独立参数形式传入 const operations over(Math.max, Math.min); operations(1, 2, 3, 4); // [4, 1]属性提取谓词不一定要是函数——直接传属性名字符串即可。over会在内部把name这类字符串自动转换为属性访问器const getProperties over([name, age]); getProperties({ name: John, age: 30 }); // [John, 30]条件检查对象匹配简写传入普通对象时谓词会被转换为“部分对象匹配”判断返回booleanconst validators over([ { name: John }, // 对象匹配 { age: 30 }, ]); validators({ name: John, age: 30 }); // [true, true]嵌套路径属性简写支持a.b.c形式的嵌套路径一次调用即可抽取深层结构中的多个字段const data { user: { name: John, profile: { age: 30 } }, settings: { theme: dark }, }; const getInfo over([user.name, user.profile.age, settings.theme]); getInfo(data); // [John, 30, dark]参数与返回值项目说明...iterateesArrayFunction \| string \| object \| Array类型的谓词列表可整体作为数组传入也可作为多个独立参数传入返回值(...args: any[]) any[]即一个接受任意实参、把各谓词结果收集为数组的函数三、源码解析一个 over 函数如何被构建over的实现位于 over.ts核心逻辑只有三步export function overT( ...iteratees: Array((...args: any[]) T) | ReadonlyArray(...args: any[]) T ): (...args: any[]) T[] { if (iteratees.length 1 Array.isArray(iteratees[0])) { iteratees iteratees[0]; } const funcs iteratees.map(item iteratee(item as Iteratee)); return function (this: unknown, ...args: unknown[]) { return funcs.map(func func.apply(this, args)); }; }三步分别对应三个关键设计数组归一化over.ts#L32-L34若调用形式为over([f1, f2])单个参数且是数组先摊平为over(f1, f2)使两种调用方式归一到同一条处理路径。谓词编译over.ts#L36在创建阶段而非每次调用阶段把每个谓词交给iteratee统一转换。也就是说简写解析只做一次之后每次调用只是直接执行已编译好的函数数组。this 透传over.ts#L38-L40返回的函数通过func.apply(this, args)把自身的this绑定原样传递给每个谓词。这不是可有可无的细节——测试用例专门验证了该行为// 来自 over.spec.tsiteratees 继承外部 this 绑定 const func over( function (this: any) { return this.b; }, function (this: any) { return this.a; } ); const object { func, a: 1, b: 2 }; object.func(); // [2, 1]四、iterateeover 背后的简写引擎over之所以能接受字符串、对象、[属性, 值]对这类非函数输入是因为每个谓词都经过 iteratee.ts 转换。其分派规则iteratee.ts#L69-L91如下输入类型转换结果底层函数null/undefined恒等函数原样返回第一个实参identity函数原样返回—长度为 2 的数组[prop, value]“属性-值相等”判断matchesProperty普通对象部分对象匹配判断matches字符串 / 数字 / symbol属性键属性访问器支持嵌套路径property这个分派表直接决定了over的行为边界。例如// nullish 谓词退化为 identity取回第一个实参 const func over(undefined, null); func(a, b, c); // [a, a] // [a, 1]直接作为参数是 property 简写[[a, 1]]包在数组里才是 matchesProperty let func over([a, 1]); func({ a: 1, 1: 2 }); // [1, 2] // 取属性 a 与属性 1 的值 func over([[a, 1]]); func({ a: 1 }); // [true] // 判断 a 1上面这组用例来自 over.spec.ts 的“should differentiate betweenpropertyandmatchesPropertyshorthands”测试它揭示了over中最容易踩坑的一点[a, 1]作为单个参数传入时会被当作property简写两个属性键只有包成[[a, 1]]时才被识别为matchesProperty。这一语义与 Lodash 保持一致是兼容层设计的一部分。完整测试矩阵还覆盖了matches简写{ b: 1 }部分对象匹配、嵌套迭代器[[b, a], [c, d]]全部按matchesProperty处理、参数透传谓词收到完整实参列表[a, b, c]、空迭代器列表over([])返回恒返回[]的函数等场景全部可在 over.spec.ts 中核对。五、导出路径over通过 compat 聚合入口导出见 compat.ts第 289 行export { over } from ./util/over.ts;因此业务代码应统一从es-toolkit/compat子路径导入与文档示例一致。六、性能权衡为什么官方推荐原生 map文档开头的 warning 并非客套话。对照第三节源码可以看清开销来源创建阶段每个谓词都要走一次iteratee分派与对象查找调用阶段每次调用都执行funcs.map(func func.apply(this, args))即一次map分配 N 次apply调用。而从源码结构看这些开销与最终执行的是Math.max还是属性读取无关是over作为兼容层“统一谓词入口”的固有成本。因此纯函数列表场景如over([Math.max, Math.min])没有简写转换的收益直接用[f1(...args), f2(...args)]或funcs.map(f f(...args))更省需要简写匹配语义属性提取、部分对象匹配、matchesProperty时over才有不可替代的价值——它把 Lodash 风格的“字符串即访问器”体验完整搬进了 es-toolkit 的 compat 层。选型建议可以概括为要 Lodash 简写语义就用over只要把同一组参数传给多个函数用原生map/ 手写数组字面量。七、参考文件文件说明docs/ja/compat/reference/util/over.md本文的主体文档over 函数 API 说明src/compat/util/over.tsover 函数实现src/compat/util/over.spec.tsover 测试用例简写分派、this 绑定、空列表等src/compat/util/iteratee.ts谓词简写 → 函数的统一转换器src/compat/compat.tscompat 聚合导出入口【免费下载链接】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),仅供参考