ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

es-toolkit negate 函数完全指南:一行代码反转布尔谓词,重塑过滤与条件逻辑

es-toolkit negate 函数完全指南:一行代码反转布尔谓词,重塑过滤与条件逻辑 es-toolkit negate 函数完全指南一行代码反转布尔谓词重塑过滤与条件逻辑【免费下载链接】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导读negate是 es-toolkit 在 Function 模块 中提供的高阶函数工具它接收一个返回布尔值的函数谓词并返回一个逻辑结果完全相反的新函数。在数组过滤、条件判断、断言组合等场景中negate能让你用「正向思维」定义规则再通过取反复用同一份逻辑避免重复书写!表达式或冗余的反向谓词。读完本文你将掌握negate的 API 签名、源码级实现原理、与Array.prototype.filter的搭配技巧以及它与 lodash 兼容版本negate的行为差异。一、negate是什么反转布尔结果的函数工厂negate是典型的「高阶函数」higher-order function它不直接参与业务计算而是接收一个函数、返回一个新函数。其核心职责在官方文档英文版、日文版中被定义为创建一个新函数将「返回 true 或 false 的函数」的返回值反转。用一个最简单的类型签名即可概括其行为const negatedFunc negate(booleanFunc);booleanFunc接收任意参数并返回布尔值negatedFunc与booleanFunc接收完全相同的参数但返回值永远是!booleanFunc(...)的结果。适用场景negate最适合用于反转条件函数或过滤逻辑。例如你已经写好了一个「判断偶数」的函数想得到「判断奇数」的函数无需重写一遍n % 2 ! 0直接negate(isEven)即可。这种「定义一次、双向复用」的思路在条件组合密集的代码中能显著减少重复与出错概率。二、快速上手基本用法与数组过滤实战从 negate 官方文档 的示例出发negate的标准导入方式与基本用法如下import { negate } from es-toolkit/function; // 基本的な使用法基本用法 const isEven (n: number) n % 2 0; const isOdd negate(isEven); console.log(isEven(2)); // true console.log(isOdd(2)); // false console.log(isEven(3)); // false console.log(isOdd(3)); // true // 配列フィルタリングで使用用于数组过滤 const numbers [1, 2, 3, 4, 5, 6]; const evenNumbers numbers.filter(isEven); console.log(evenNumbers); // [2, 4, 6] const oddNumbers numbers.filter(negate(isEven)); console.log(oddNumbers); // [1, 3, 5]上面的示例揭示了negate最典型的实战组合filter与negate天然互补。filter保留谓词返回true的元素negate负责把谓词反转于是filter(negate(pred))就等价于「过滤掉满足pred的元素」。文档还给出了对复杂条件函数取反的示例——反转字符串长度判断import { negate } from es-toolkit/function; const isLongString (str: string) str.length 5; const isShortString negate(isLongString); const words [hi, hello, world, javascript]; const longWords words.filter(isLongString); console.log(longWords); // [javascript] const shortWords words.filter(isShortString); console.log(shortWords); // [hi, hello, world]注意isLongString与isShortString接收的参数一个字符串和返回类型布尔值完全一致这正是negate类型保真type-preserving的体现入参签名不变只翻转返回值。三、API 参考参数与返回值negate(func)项目说明参数func类型F一个返回布尔值的函数谓词函数F被约束为(...args: any[]) boolean返回值类型F一个新函数与原函数接收相同参数但返回相反的布尔值关键点有二参数透传返回的新函数与func拥有完全一致的参数列表调用时原样透传因此negate不会破坏原有函数的调用约定类型保留从源码可见negate的返回类型直接复用泛型F而不是简单地返回(...args: any[]) boolean。这意味着在 TypeScript 中const isOdd: (n: number) boolean negate(isEven)的类型推断是精确的不会退化成宽泛的函数类型。四、源码解析三行核心实现与 lodash 兼容版的差异4.1 核心实现es-toolkit 原生版negate的核心实现位于 src/function/negate.ts全文仅有一个导出函数export function negateF extends (...args: any[]) boolean(func: F): F { return ((...args: any[]) !func(...args)) as F; }从源码结构可以提炼出三条实现事实闭包捕获返回的箭头函数通过闭包持有func并在每次调用时执行!func(...args)用逻辑非!对结果取反this绑定不传递原生版返回的是箭头函数箭头函数不绑定自己的this因此调用negatedFunc时外层的this不会被传入func。对于纯函数式谓词如isEven这毫无影响但如果你的谓词依赖this请留意这一点无参数校验原生版没有对func做类型检查直接调用!func(...args)。若传入非函数会在运行时抛出TypeError类型层面则由泛型约束F extends (...args: any[]) boolean在编译期拦截。对应的单元测试位于 src/function/negate.spec.ts使用 vitest 验证了三个关键行为negate的返回值是一个函数typeof negate(() true) function布尔结果被正确反转negate(() true)()为falsenegate(() false)()为true与filter组合后能正确筛出奇数[1, 2, 3, 4, 5, 6].filter(negate(isEven))等于[1, 3, 5]。4.2 lodash 兼容版compat 模块es-toolkit 还提供与 lodash 行为对齐的兼容版本实现在 src/compat/function/negate.ts。对比两者兼容版存在三处显著差异显式校验兼容版在调用前检查typeof func ! function不满足时抛出TypeError(Expected a function)与 lodash 的报错行为一致this绑定传递兼容版返回普通函数function (this: any, ...args: any[])并通过func.apply(this, args)把调用时的this透传给原函数行为更贴近 lodash 语义双重重载签名兼容版同时导出了基于元组类型T extends any[]的签名与基于函数类型F的签名为不同调用场景提供更灵活的类型推导。如果项目从 lodash 迁移且依赖其this传递语义应优先选用 compat 入口见下文「如何引用」如果追求极致的包体积与简单性原生版是更优选择。五、组合与边界negate的进阶用法5.1 与filter、some、every等方法的组合negate不仅适用于数组过滤凡是以谓词为参数的 API 都能与其组合import { negate } from es-toolkit/function; const isEven (n: number) n % 2 0; const numbers [1, 2, 3, 4, 5, 6]; // 是否存在奇数 console.log(numbers.some(negate(isEven))); // true // 是否全部为奇数 console.log(numbers.every(negate(isEven))); // false // 找到第一个奇数 console.log(numbers.find(negate(isEven))); // 1 // 第一个奇数的下标 console.log(numbers.findIndex(negate(isEven))); // 0由于negate返回的函数与原函数签名一致这些内建数组方法的回调位置都能直接接受negate(...)的产物无需额外包装。5.2 链式取反与语义可读性negate(negate(fn))在逻辑上等价于fn本身因此一般不需要双重取反。更常见的需求是先组合、后取反例如把多个条件用组合成谓词后再整体取反negate依然适用因为它只关心入参函数的布尔返回值不关心谓词内部逻辑有多复杂。5.3 注意事项negate期望入参返回「可被!归一化为布尔值」的值虽然 JavaScript 的!对任意值都成立但把非布尔返回值如0、、null传入negate后取反结果会基于真值truthiness语义而不是字面意义上的「相反值」原生版不传递this若谓词内部使用了this例如对象方法建议改用 compat 版或先用bind固定上下文negate每次调用都会创建新的闭包在热路径中反复创建会带来微量开销但现代 JS 引擎对此优化良好常规业务场景无需顾虑。六、如何引用从安装到按需导入negate随 es-toolkit 的 Function 模块一起发布可以通过两种路径导入// 方式一按模块导入推荐利于 tree shaking import { negate } from es-toolkit/function; // 方式二从主入口导入整个库统一入口 import { negate } from es-toolkit;从 src/index.ts 可以看到negate经由export * from ./function/index.ts被聚合到主入口而 src/function/index.ts 则显式export { negate } from ./negate.ts作为模块内导出。因此两种写法均有效按需导入可让打包器只保留实际用到的代码契合 es-toolkit 主打的小体积与 tree shaking 特性。lodash 兼容行为则从 compat 入口引用import { negate } from es-toolkit/compat;安装方式与仓库其他功能一致通过npm install es-toolkit安装后即可使用完整文档可参考 docs/reference/function/negate.md 及各语言版本日文版、中文版。七、总结negate是一个「小而美」的高阶函数核心实现仅一行逻辑非运算却能在过滤、断言、条件组合等场景中消除大量重复代码。回顾本文要点行为接收布尔谓词返回参数签名相同、布尔结果相反的新函数典型组合filter(negate(pred))即「排除满足 pred 的元素」some/every/find同理实现差异原生版src/function/negate.ts极简且不传thiscompat 版src/compat/function/negate.ts带参数校验、透传this并贴近 lodash 语义可靠性行为由 src/function/negate.spec.ts 的单元测试覆盖验证。下次当你写出!somePredicate(x)或被迫定义两个语义相反的谓词时先想想negate——一行取反逻辑更清晰。【免费下载链接】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),仅供参考
返回列表