es-toolkit `unary` 使用指南:限制函数最多接收一个参数(Lodash 兼容实现)
2026/9/16 20:55:17 网站建设 项目流程

es-toolkitunary使用指南:限制函数最多接收一个参数(Lodash 兼容实现)

【免费下载链接】es-toolkitA modern JavaScript utility library that's 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit

unaryes-toolkit/compat(Lodash 兼容模块)提供的一个函数工具,它将目标函数包装为最多只接收一个参数的新函数,超出部分会被静默忽略。它的典型应用场景是配合Array.prototype.map这类会向回调传递多余参数的高阶方法,解决parseInt被传入索引参数而返回NaN这类经典问题。读完本文你将掌握unary的调用方式、参数与返回值语义、与ary的关系,以及它在源码层面的实现原理。

概览:一行代码锁定参数个数

const limitedFunc = unary(func);

与 Lodash 的unary完全对齐,es-toolkit的兼容版unary(func)返回一个新函数,该函数调用原始func只透传第一个参数,其余参数一律丢弃。

import { unary } from 'es-toolkit/compat';

注意:该函数位于compat入口,用于 Lodash 兼容场景;现代es-toolkit主入口同样提供unary,两者的行为一致(见下文源码分析)。

使用方式:unary(func)

当你想让一个函数"最多只接收一个参数"时,就用unary包装它。任何额外传入的参数都会被忽略。

基础示例:截断多余参数

import { unary } from 'es-toolkit/compat'; function greet(name, greeting, punctuation) { return `${greeting} ${name}${punctuation}`; } // 转换为只接收第一个参数的函数 const greetOne = unary(greet); greetOne('Alice', 'Hello', '!'); // 等价于 greet('Alice'),返回 'undefined Aliceundefined'

这里greetOne内部只会把'Alice'传给greet'Hello''!'被丢弃,因此greetingpunctuation均为undefined

实战场景:修复map(parseInt)的经典陷阱

unary最常见的用途是与数组的map方法配合。Array.prototype.map会向回调传递三个参数(当前元素、索引、整个数组),而parseInt本身接收两个参数(字符串与进制基数),二者叠加会产生意想不到的结果:

const numbers = ['1', '2', '3']; numbers.map(parseInt); // [1, NaN, NaN] —— 意外结果 // 实际执行的是 parseInt('2', 1)、parseInt('3', 2),进制非法导致 NaN numbers.map(unary(parseInt)); // [1, 2, 3] —— 正确结果 // 索引与数组参数被丢弃,parseInt 只拿到字符串,默认按十进制解析

这正是"截断回调多余参数"这一模式的经典应用,也解释了为什么函数式编程中常常需要对回调做参数限制。

参数与返回值

  • func(...args: any[]) => any):需要限制参数个数的目标函数。
  • 返回值(...args: any[]) => any):一个新的函数,最多只接收一个参数。

注意,unary不会强制最小参数数量:即使调用返回函数时不传任何参数,它也会正常执行(传入空参数列表),这一点在源码测试中有明确覆盖。

源码实现:unaryary的特例

es-toolkit的兼容版unary实现极为精简,位于 src/compat/function/unary.ts,其核心只有一行:

import { ary } from './ary.ts'; export function unary<T, U>(func: (arg1: T, ...args: any[]) => U): (arg1: T) => U { return ary(func, 1); }

即:unary(func)等价于ary(func, 1),也就是把参数上限固定为 1 的ary调用。

继续追踪调用链,兼容版的ary位于 src/compat/function/ary.ts,它负责处理参数校验与默认值后,转交给主入口的 src/function/ary.ts 完成真正的截断逻辑:

// src/compat/function/ary.ts(节选) if (Number.isNaN(n) || n < 0) { n = 0; } return aryToolkit(func, n);
// src/function/ary.ts(节选) export function ary<F extends (...args: any[]) => any>(func: F, n: number): (...args: any[]) => ReturnType<F> { return function (this: any, ...args: Parameters<F>) { return func.apply(this, args.slice(0, n)); }; }

可以看到底层机制非常简单:包装函数通过args.slice(0, n)只保留前n个参数,再用func.apply(this, ...)调用原函数——this绑定被完整保留(这在测试中有专门用例验证,见 src/compat/function/unary.spec.ts)。unary场景下n = 1,因此slice(0, 1)恰好只留下第一个参数。

为什么文档建议优先使用ary

原文档(docs/ja/compat/reference/function/unary.md)明确给出警告:由于unary只是ary的特殊情况,当需要更多控制(例如限制为 2 个、3 个参数或 0 个参数)时,应直接使用现代es-toolkitary,例如:

import { ary } from 'es-toolkit/function'; // 限制为 0 个参数 ary(fn, 0)(1, 2, 3); // [] // 限制为 2 个参数 ary(fn, 2)(1, 2, 3); // [1, 2]

详细用法可参考 ary 官方文档 与 兼容版 ary 文档。此外,兼容版ary还支持省略n时默认取func.length,并带有参数校验(负数或NaN归零)与 lodash 风格的guard保护逻辑,灵活性远超固定为 1 的unary

测试验证:三个关键行为

仓库中的单元测试 src/compat/function/unary.spec.ts 使用 Vitest 编写,覆盖了unary的三个核心契约:

  1. 截断多余参数map(['6', '8', '10'], unary(parseInt))的结果为[6, 8, 10],验证了与map配合时的正确行为;
  2. 不强制最小参数个数unary(fn)()不传任何参数也能正常调用并返回[]
  3. 保留this绑定:将包装后的函数作为对象方法调用时,this正确指向该对象。

这三条用例从行为层面对应了上文源码中的slice(0, 1)func.apply(this, ...)实现,可作为你理解与验证unary语义的直接依据。

小结

  • unary(func)返回一个最多接收一个参数的新函数,多余参数被忽略;
  • 经典用法是配合map等会传递多余参数的高阶方法,修复parseIntNaN陷阱;
  • 源码层面unaryary(func, 1),底层通过args.slice(0, n)+func.apply(this, ...)实现;
  • 需要更灵活的参数上限控制时,建议改用功能更全的ary

【免费下载链接】es-toolkitA modern JavaScript utility library that's 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询