news 2026/9/15 16:24:17

es-toolkit compat 的 entriesIn / toPairsIn:将对象(含继承属性)转换为键值对数组的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
es-toolkit compat 的 entriesIn / toPairsIn:将对象(含继承属性)转换为键值对数组的完整指南

es-toolkit compat 的 entriesIn / toPairsIn:将对象(含继承属性)转换为键值对数组的完整指南

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

entriesIn是 es-toolkit 兼容层(es-toolkit/compat)中toPairsIn的别名,二者在功能上完全等价:把对象、MapSet转换为[key, value]键值对数组,并且会包含原型链上的可枚举继承属性。本文以 entriesIn 官方参考文档 为骨架,结合其指向的 toPairsIn 完整文档 以及仓库源码,系统讲解该函数的用法、边界行为、底层实现与性能注意事项,读完即可在需要遍历"自有 + 继承"属性键值对的场景中正确选用它。

entriesIn 是什么:一个指向 toPairsIn 的别名

在 es-toolkit 的 compat 层中,entriesIn并非独立实现,而是toPairsIn的直接导出别名。官方文档对此有明确说明:

entriesInis an alias oftoPairsIn. See thetoPairsIndocumentation for details.

从源码可以印证这一点。entriesIn.ts 全文只有一行:

export { toPairsIn as entriesIn } from './toPairsIn.ts';

也就是说,entriesIntoPairsIn是同一个函数引用,二者用法、返回值、边界行为完全一致。这也是为什么官方文档将entriesIn作为别名收录在 toPairsIn 页面之下,并为其单独保留了重定向文档。

在测试用例中同样验证了这一别名关系。entriesIn.spec.ts 的核心断言就是:

it('should be an alias of toPairsIn', () => { expect(entriesIn).toBe(toPairsIn); });

基础用法:把对象转换为键值对数组

使用entriesIn(或等价的toPairsIn)时,从es-toolkit/compat导入即可:

import { toPairsIn } from 'es-toolkit/compat'; // 普通对象转换 const object = { a: 1, b: 2 }; toPairsIn(object); // => [['a', 1], ['b', 2]]

它的类型签名(见 toPairsIn.ts)支持两种形态:

export function toPairsIn<T>(object?: Record<string, T> | Record<number, T>): Array<[string, T]>; export function toPairsIn(object?: object): Array<[string, any]>;
  • 参数object:要转换的对象(普通对象、MapSet均可)。参数是可选的,传入nullundefined时返回空数组[]
  • 返回值Array<[string, any]>,即键值对数组,包含继承属性

与 toPairs 的关键区别:包含原型链属性

toPairsIntoPairs最大的不同在于:toPairsIn会枚举原型链上的可枚举属性,而toPairs只处理对象自身的属性。

官方文档给出的继承属性示例:

import { toPairsIn } from 'es-toolkit/compat'; function Parent() { this.inherited = 'value'; } Parent.prototype.proto = 'property'; const child = new Parent(); child.own = 'own'; toPairsIn(child); // => [['inherited', 'value'], ['own', 'own'], ['proto', 'property']]

可以看到,constructor之后的原型属性proto、构造函数内赋值的inherited以及实例自身的own都被纳入了结果。

对应的测试用例见 toPairsIn.spec.ts:Foo.prototype.b = 2会被正确收录进结果数组。

对 Map 与 Set 的特殊处理

除了普通对象,toPairsIn还能直接转换MapSet,这是它与原生Object.entries()的一个重要差异(Object.entriesMap/Set只会返回空数组)。

官方文档示例:

import { toPairsIn } from 'es-toolkit/compat'; // Map 对象转换 const map = new Map([ ['key1', 'value1'], ['key2', 'value2'], ]); toPairsIn(map); // => [['key1', 'value1'], ['key2', 'value2']] // Set 对象转换 const set = new Set([1, 2, 3]); toPairsIn(set); // => [[1, 1], [2, 2], [3, 3]]

注意Set的转换规则:每个元素被映射为[value, value]形式(键和值相同),而不是[index, value]。这一行为在 toPairsIn.ts 中通过类型分支实现:

if (object instanceof Set) { return setToEntries(object); } if (object instanceof Map) { return mapToEntries(object); }

对应的 setToEntries.ts 实现为:

export function setToEntries<T>(set: Set<T>): Array<[T, T]> { const arr = new Array<[T, T]>(set.size); const values = set.values(); for (let i = 0; i < arr.length; i++) { const value = values.next().value as T; arr[i] = [value, value]; } return arr; }

而 mapToEntries.ts 则通过并行迭代Map的 keys 与 values 迭代器来组装结果:

export function mapToEntries(map: Map<any, any>) { const arr = new Array(map.size); const keys = map.keys(); const values = map.values(); for (let i = 0; i < arr.length; i++) { arr[i] = [keys.next().value, values.next().value]; } return arr; }

测试用例 toPairsIn.spec.ts 分别验证了Map[['a', 1], ['b', 2]])与Set[[1, 1], [2, 2]])的转换结果。

底层实现:keysIn 与遍历逻辑

对于普通对象,toPairsIn并不直接使用for...in,而是先调用 compat 层的keysIn获取"自有 + 继承"的键集合,再逐键取值组装:

const keys = keysInToolkit(object); const result: Array<[key: string, value: any]> = new Array(keys.length); for (let i = 0; i < keys.length; i++) { const key = keys[i]; const value = object[key as keyof typeof object]; result[i] = [key, value]; } return result;

(见 toPairsIn.ts)

其中keysIn(见 keysIn.ts)承担了复杂的键收集逻辑:

  • 传入null/undefined时返回空数组;
  • 类数组对象isArrayLike)按数组语义处理,为每个索引生成字符串形式的键,再合并其余继承键;
  • 原型对象isPrototype)会过滤掉constructor键;
  • 对普通对象则退化为for...in收集所有可枚举键(见keysInImpl,keysIn.ts)。

这也解释了为什么toPairsIn能正确处理字符串、带length属性的对象等特殊输入。测试用例验证了这类边界:

// 字符串转换(见 toPairsIn.spec.ts L74-L82) toPairsIn('xo'); // => [['0', 'x'], ['1', 'o']] // 带 length 属性的对象(见 toPairsIn.spec.ts L43-L52) const object = { '0': 'a', '1': 'b', length: 2 }; toPairsIn(object); // => [['0', 'a'], ['1', 'b'], ['length', 2]]

性能提示:何时应该改用原生 API

官方文档在 toPairsIn 页面顶部给出了明确的警告:

由于要处理继承属性、MapSet等复杂逻辑,toPairsIn的运行速度较慢。如果不需要继承属性,请使用更快、更现代的Object.entries();如果需要继承属性,请直接使用for...in循环。

原因从源码结构即可看出:toPairsIn的完整调用链包含instanceof判断、keysIn内部的isArrayLike/isPrototype/isTypedArray/isBuffer等多项检测,加上对Map/Set迭代器的封装,比原生 API 的常数开销大得多。

实际选型建议:

需求推荐方案
只需对象自身可枚举属性Object.entries(object)(原生,最快)
需要含继承属性的键值对for...in循环 + 手动收集,或toPairsIn
需要转换Map/SettoPairsIn(map)/toPairsIn(set),或手动Array.from(map)

边界行为与注意事项总结

综合文档、源码与测试,entriesIn/toPairsIn的关键行为可归纳如下:

  1. 空值安全:传入nullundefined返回[],不会抛错(toPairsIn.ts,测试见 toPairsIn.spec.ts);
  2. 继承属性包含:原型链上的可枚举属性会出现在结果中,这是与toPairsObject.entries()的本质区别;
  3. Map:按插入顺序输出[key, value]对;
  4. Set:输出[value, value]对(键值相同);
  5. 结果顺序:普通对象的输出顺序取决于for...in的枚举顺序(字符串键按插入序、整数键按升序),对顺序敏感的场景建议自行排序;
  6. 别名等价entriesIntoPairsIn是同一个函数,可互换使用。

如需进一步阅读完整文档与实现,可参考 toPairsIn 参考文档、toPairsIn 源码、keysIn 源码 及对应的 toPairsIn 测试。

【免费下载链接】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/15 16:23:40

SmartDNS 本地DNS落地实践:按家庭角色拆分上游

SmartDNS 本地DNS落地实践&#xff1a;按家庭角色拆分上游 【免费下载链接】smartdns A local DNS server to obtain the fastest website IP for the best Internet experience, support DoT, DoH, DoQ. 一个本地DNS服务器&#xff0c;获取最快的网站IP&#xff0c;获得最佳上…

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

ActiveX调用MATLAB在CVI和LabVIEW中的混合编程实践

简介&#xff1a;面向需要在Matlab与LabWindows/CVI、LabVIEW之间实现双向数据交互的工程师与科研人员&#xff0c;资源围绕ActiveX技术提供了可运行的完整工程示例&#xff0c;帮助解决跨软件调用测试程序、传递采集数据等常见集成需求。压缩包共21个文件&#xff0c;以C语言源…

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

用Python和Pygame实现围棋小游戏:规则建模、提子判定与AI对战

简介&#xff1a;用 Python 与 Pygame 编写的围棋小游戏完整源码项目&#xff0c;适合想通过实战入门游戏开发的 Python 初学者、Pygame 学习者&#xff0c;以及想了解围棋规则与简单 AI 算法的开发者。整体代码量精简、模块划分清楚&#xff0c;可直接运行体验&#xff0c;也适…

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

Haystack 集成指南:使用 YouComWebSearch 组件接入 You.com 搜索 API

Haystack 集成指南&#xff1a;使用 YouComWebSearch 组件接入 You.com 搜索 API 【免费下载链接】haystack Open-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows wit…

作者头像 李华