news 2026/9/16 20:28:50

es-toolkit compat 层 constant 函数详解:创建始终返回固定值的函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
es-toolkit compat 层 constant 函数详解:创建始终返回固定值的函数

es-toolkit compat 层 constant 函数详解:创建始终返回固定值的函数

【免费下载链接】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

es-toolkit 为兼容 Lodash 使用习惯,在 compat 兼容子包中实现了constant函数:它接收一个值并返回一个闭包,该闭包无论被调用多少次、以何种参数调用,都恒定返回当初传入的那个值。本文基于官方文档 constant (Lodash 互換性) 与仓库源码 src/compat/util/constant.ts,完整讲解constant的签名、类型系统、典型使用场景(高阶函数回调、默认值提供、对象引用保持),并通过测试用例 src/compat/util/constant.spec.ts 印证其对 falsy 值、NaN、调用上下文等边缘行为的实现细节。

读完本文,你将掌握:如何正确导入和使用constant,它与普通箭头函数的取舍,以及源码层面“返回同一对象引用”这一语义是如何保证的。

官方提示:优先使用箭头函数

在展开用法之前,需要先说明文档中一个醒目的告警(原文以::: warning标注):

这个constant函数会为简单任务创建一个额外的函数包装器,产生不必要的开销。对于这类简单需求,建议使用更简单、更直观的内联箭头函数。

也就是说,如果只是要一个“永远返回固定值”的函数,() => 42这样的内联箭头函数通常更直接。constant的价值在于Lodash 生态的代码迁移兼容,以及在“同一个常量函数被多处复用、传递”的场景中,把创建动作与取值动作分离。理解这一点,才能正确判断何时该用它。

函数签名与类型定义

constant的文档定义如下:

const constantFunction = constant(value);

在源码 src/compat/util/constant.ts 中,它通过两个重载声明精确刻画了类型行为:

export function constant<T>(value: T): () => T; export function constant<T>(value?: T): () => T | undefined;

两个重载的分工是:

  • 当显式传入value时,第一个重载生效,返回函数类型为() => T——精确锁定为传入值的类型,调用方拿到的是强类型结果;
  • 当不传参数时,走第二个重载,返回类型退化为() => T | undefined,调用结果可能是undefined

文档中的参数与返回值说明与此一致:

参数
  • valueT,可选):函数要返回的值。不提供时返回undefined
返回值

() => T | undefined:返回一个始终返回所给值的新函数。

注意参数是可选的,这与部分同类工具“必须传值”的实现不同;下面“不传参数”的行为在测试用例中有专门覆盖。

基本用法:创建一个恒定返回函数

constant适用于“需要一个始终返回特定值的函数”的场景,在函数式编程中常用于提供默认值或作为回调函数。

import { constant } from 'es-toolkit/compat'; // 基本用法 const always42 = constant(42); console.log(always42()); // 42 const alwaysHello = constant('hello'); console.log(alwaysHello()); // "hello"

导入路径是es-toolkit/compat,这是 es-toolkit 提供的 Lodash 兼容入口;constant正是通过该入口聚合导出的——在 src/compat/compat.ts 第 277 行可以看到export { constant } from './util/constant.ts'这一导出语句。

结合 map 等高阶函数使用

constant最典型的用途是作为数组map等高阶函数的回调,一次性把所有元素替换为同一个常量。

import { constant } from 'es-toolkit/compat'; // 所有元素填 0 const numbers = [1, 2, 3, 4, 5]; const zeros = numbers.map(constant(0)); console.log(zeros); // [0, 0, 0, 0, 0] // 所有元素替换为同一个对象 const users = ['alice', 'bob', 'charlie']; const defaultUser = users.map(constant({ role: 'user', active: true })); console.log(defaultUser); // [{ role: 'user', active: true }, { role: 'user', active: true }, { role: 'user', active: true }]

这个写法在仓库内部也被实际使用:例如 src/compat/util/method.spec.ts 和 src/compat/util/methodOf.spec.ts 中都出现了times(3, constant)这样的组合——用times生成重复值数组时以constant作为迭代回调。而在 src/compat/util/iteratee.spec.ts 中,还能看到values.map(esToolkit.constant(object))的用法,即对一组值批量套用同一个常量函数。

值得一提的是,仓库中cond(条件分支组合函数)的官方示例也依赖constant作为各分支的“返回固定值”动作(见 src/compat/util/cond.ts 的 JSDoc 示例):

const func = cond([ [matches({ a: 1 }), constant('matches A')], [conforms({ b: isNumber }), constant('matches B')], [stubTrue, constant('no match')] ]);

作为条件默认值提供器

constant还可以用作默认参数,配合逻辑或运算实现“有值用值、无值回退”的模式:

import { constant } from 'es-toolkit/compat'; function processData(data, fallback = constant('默认值')) { return data || fallback(); } console.log(processData(null)); // "默认值" console.log(processData('实际数据')); // "实际数据"

这里constant('默认值')把“默认值”封装成一个可多次求值的函数,调用侧通过fallback()显式取值。这与直接写fallback = '默认值'语义等价,但更贴近 Lodash 风格代码中“回调即接口”的迁移场景。

保持对象引用:返回同一个对象,而非副本

对于对象值,constant返回的不是克隆,而是对原对象的引用保持。这一点有文档示例和测试用例双重佐证:

import { constant } from 'es-toolkit/compat'; const obj = { a: 1 }; const getObj = constant(obj); console.log(getObj() === obj); // true (同一个对象引用)

在源码层面,实现就一行核心逻辑(见 src/compat/util/constant.ts 第 24-26 行):

export function constant<T>(value?: T): () => T | undefined { return () => value; }

闭包直接捕获形参value,没有任何拷贝或惰性求值,因此每次调用getObj()都返回同一份引用——对引用类型尤其要注意这一点,多处拿到的“同一个对象”是共享状态,修改任意一处会影响其他调用方的结果。

对应的测试 src/compat/util/constant.spec.ts 第一条用例断言了result === objectevery检查所有结果都严格等于原对象),与源码行为一致。

测试用例揭示的边缘行为

继续阅读 src/compat/util/constant.spec.ts,可以看到三个值得注意的实现细节:

  1. 调用上下文与多余参数被完全忽略。测试中先通过constant(object)创建_constant,然后分别以_constant.call({})(改变this)和_constant(value)(传入多余实参)两种方式调用,断言结果始终=== object。这验证了内部闭包() => value不依赖this、也不读形参的特性——它比很多“具名函数”实现更纯粹的无状态。
  2. falsy 值全部正确透传。测试使用仓库内部的falsey数据集(含false0''NaNnullundefined等)逐一验证constant(value)()的返回结果,并对NaN特判result !== result && value !== value(即NaN === NaN不成立时的相等语义)。也就是说constant(0)()constant('')()constant(false)()都能准确返回对应 falsy 值,不会被误判。
  3. 不传参数时返回undefined。测试用例index ? constant(value) : constant()覆盖了零参调用路径,与重载声明value?: T的可选语义对应。
  4. Lodash 的链式(Chaining)支持不在范围内。测试文件尾部明确注释 “Chaining is out of scope for es-toolkit”,_(true).constant()相关的用例被注释掉了——即 compat 层的constant只做纯函数兼容,不提供 Lodash 链式调用包装,迁移链式代码时需注意这一边界。

与 stub 系列函数的关系

constant是“任意值的通用版”,而仓库 compat 层的 util 目录下还提供了一组固定返回特定值的stub函数(stubTruestubFalsestubObjectstubArraystubString,参考 src/compat/util/stubTrue.ts 及其对应的文档 docs/ja/compat/reference/util/stubTrue.md 等)。从stubTrue的源码可以看到其返回类型被精确标注为true,这类 stub 函数本质上是constant(true)的特化。当返回类型固定且希望类型系统锁定到字面量时,优先选 stub 系列;当返回任意自定义值时,使用constant

小结

  • constant(value)创建一个闭包,恒返回value;参数可选,不传时返回函数结果恒为undefined
  • 类型上通过双重载实现:传参时精确推导() => T,缺参时退化为() => T | undefined
  • 典型场景:map等高阶函数回调、默认值提供器、cond等组合函数中返回固定分支值;对象值保持同一引用,多处共享同一状态。
  • 官方建议:简单场景优先使用内联箭头函数,constant主要用于 Lodash 迁移兼容与常量函数复用;Lodash 链式用法不在 es-toolkit 的兼容范围内。

相关文档可参考英文版 constant (Lodash Compatibility),实现与测试分别位于 src/compat/util/constant.ts 与 src/compat/util/constant.spec.ts。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 20:26:00

企业官网建设:展示型与获客型的技术架构与策略

1. 企业官网的核心定位之争这个问题困扰着无数企业主和营销负责人。上周刚帮一家制造业客户重新规划官网&#xff0c;老板开门见山就问&#xff1a;"我们每年花十几万维护的官网&#xff0c;到底该做成电子版宣传册还是销售漏斗&#xff1f;"这其实反映了企业官网建设…

作者头像 李华
网站建设 2026/9/16 20:25:43

CentOS 7 GNOME桌面无限转圈?SELinux安全上下文修复实录

先交代一下背景&#xff1a;我这边遇到的情况是VMware虚拟机里装好了CentOS 7的GNOME桌面&#xff0c;第一次重启还能进系统&#xff0c;第二次启动直接卡在登录界面的“花瓣”加载动画上——转圈、转圈、再转圈&#xff0c;鼠标还能动&#xff0c;但就是进不了桌面。试过等待十…

作者头像 李华
网站建设 2026/9/16 20:23:47

STM32空气监测系统源码拆解:从ADC采样到数据可视化全流程解析

简介&#xff1a;基于STM32单片机空气监测系统设计毕业设计资料包&#xff0c;主要面向嵌入式、自动化、电子信息等专业的在校学生与开发者&#xff0c;适用于毕业设计、课程设计、项目初期演示及二次开发入门。压缩包内共包含312个文件&#xff0c;整包大小15.32MB&#xff0c…

作者头像 李华
网站建设 2026/9/16 20:22:54

大数据架构降本实践:从自建HBase/Redis迁移到Lindorm+Tair,成本降60%

1. 项目背景&#xff1a;为什么大数据架构一定要动刀降本先说个现实问题。我们团队之前维护的大数据平台&#xff0c;承担着全公司用户行为日志、订单流水、风控特征、推荐召回等核心链路的读写。高峰期日增数据量在几十TB级别&#xff0c;总存储量奔着PB去&#xff0c;组件也越…

作者头像 李华
网站建设 2026/9/16 20:22:37

Python构建招标数据采集系统:从网页解析到结构化存储

1. 项目背景与核心价值公共资源交易平台的招标数据是企业市场情报的黄金矿脉。作为一名长期从事数据采集与分析的老兵&#xff0c;我见过太多企业因为信息滞后错失商机。这个项目将带你用Python构建完整的招标数据采集系统&#xff0c;从网页解析到结构化存储&#xff0c;实现企…

作者头像 李华