es-toolkit 兼容版 toPairs:将对象、Map、Set 转为键值对数组的完整指南
【免费下载链接】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
toPairs是 es-toolkit 的 Lodash 兼容(compat)模块中提供的一个实用函数,用于将对象自身的可枚举属性转换为[key, value]形式的键值对数组,同时也能处理Map与Set。本文将基于 toPairs 参考文档 结合 compat 源码实现 与测试用例,全面讲解其用法、边界行为、底层原理,以及与原生Object.entries()的取舍,帮助你在实际项目中正确、高效地使用它。
快速上手
从es-toolkit/compat入口导入并调用:
import { toPairs } from 'es-toolkit/compat'; const pairs = toPairs(object);函数接收一个对象、Map或Set,返回对应的键值对数组。
基本用法
转换普通对象
toPairs的核心场景是把对象自身的可枚举属性转换为[key, value]数组。继承属性不会被包含:
import { toPairs } from 'es-toolkit/compat'; // 基本对象转换 const object = { a: 1, b: 2, c: 3 }; toPairs(object); // => [['a', 1], ['b', 2], ['c', 3]] // 数字键对象:键会以字符串形式保留 const numbers = { 0: 'zero', 1: 'one', 2: 'two' }; toPairs(numbers); // => [['0', 'zero'], ['1', 'one'], ['2', 'two']]这一行为在 toPairs.spec.ts 中有专门验证:即使对象通过构造函数原型链带有b = 2这样的继承属性,toPairs也只返回自身的[['a', 1]]。
转换 Map
Map会按插入顺序输出其全部键值对:
import { toPairs } from 'es-toolkit/compat'; const map = new Map(); map.set('name', 'John'); map.set('age', 30); toPairs(map); // => [['name', 'John'], ['age', 30]]转换 Set
对于Set,每个元素会以[value, value]的形式成对输出(键与值相同):
import { toPairs } from 'es-toolkit/compat'; const set = new Set([1, 2, 3]); toPairs(set); // => [[1, 1], [2, 2], [3, 3]]安全处理 null 与 undefined
toPairs对空值输入是安全的,直接返回空数组,不会抛错:
import { toPairs } from 'es-toolkit/compat'; toPairs(null); // => [] toPairs(undefined); // => []这与源码入口处if (object == null) { return []; }的防御式判断完全一致(toPairs.ts),宽松相等同时覆盖了null和undefined两种情况。
参数与返回值
| 项目 | 说明 |
|---|---|
参数object | 要转换的对象,类型为object(支持普通对象、Map、Set),可为null/undefined |
| 返回值 | Array<[string, any]>,键值对数组 |
此外,toPairs还有一个常用别名entries,两者完全等价。在 entries.ts 中可以看到别名就是直接对toPairs的再导出:
export { toPairs as entries } from './toPairs.ts';你可以按个人习惯选择toPairs或entries调用。toPairs与包含继承属性的 toPairsIn 是姊妹函数,后者使用keysIn收集键,因此会包含原型链上的可枚举属性,需要时也可以对比参考。
源码级原理
toPairs.ts 的实现采用"分类分派"策略,整体逻辑清晰:
- 空值短路:输入为
null/undefined时直接返回[]。 Set分支:调用内部工具 setToEntries,利用set.values()迭代器把每个值包装成[value, value]。Map分支:调用内部工具 mapToEntries,同时取map.keys()与map.values()两个迭代器,同步next()组装成键值对。- 普通对象分支:通过 compat 版的 keys 先拿到键列表,再预分配等长数组,逐一下标取值填充,避免动态
push带来的扩容开销。
其中keys工具本身还处理了类数组对象:当对象具有length属性时(如字符串、数组、arguments、Buffer、TypedArray 等),会生成对应的数字下标键。测试用例也覆盖了这一点——带有length: 2的对象会被完整输出[['0', 'a'], ['1', 'b'], ['length', 2]](toPairs.spec.ts),字符串'xo'和Object('xo')则输出[['0', 'x'], ['1', 'o']](toPairs.spec.ts)。
与 Object.entries() 的取舍
官方文档在开头给出了明确建议:优先使用原生Object.entries()。
原因在于,toPairs为了兼容 Lodash 的完整语义,内部需要处理Map、Set、类数组对象、Buffer、TypedArray、原型对象等大量分支,逻辑复杂导致运行速度较慢;而Object.entries()是引擎原生实现,对纯对象场景更快也更现代:
const object = { a: 1, b: 2, c: 3 }; // 现代写法 const pairs = Object.entries(object); // => [['a', 1], ['b', 2], ['c', 3]]如果你的输入确定是普通对象,且不需要Map/Set支持,直接使用Object.entries()是最佳实践。而当你需要与 Lodash 代码保持行为一致(例如迁移存量代码、处理Map/Set/ 类数组等复杂输入),toPairs则是一个可靠的兼容方案。
性能对比验证
仓库在 benchmarks/performance/toPairs.bench.ts 中内置了与 Lodash 的对比基准,分别针对普通对象、Set、Map三种输入进行vitest bench测量。你可以通过以下方式在本地复现:
# 在仓库根目录安装依赖后运行性能基准 yarn bench:performance --run benchmarks/performance/toPairs.bench.ts(具体命令以仓库 package.json 中的 scripts 为准。)借助基准结果可以直观评估 es-toolkit 的toPairs与 lodash 在各类输入下的性能差异,为"是否值得使用 compat 版"提供数据依据。
典型应用场景
- 对象 ↔ 键值对数组互转:与 fromPairs 配合,实现对象到数组再到对象的双向转换,便于排序、过滤、序列化。
- 统一异构数据结构:当上游数据可能是普通对象、
Map或Set时,用toPairs一键归一化为统一的键值对数组,后续逻辑无需再分支判断。 - Lodash 迁移:从 Lodash 项目迁移到 es-toolkit 时,
toPairs(及别名entries)可无缝替换_.toPairs/_.entries,保持原有输出行为不变。
小结
toPairs是 es-toolkit compat 模块中一个"全兼容、多输入"的键值对转换函数:普通对象只取自身可枚举属性,Map、Set、类数组对象、字符串都有对应处理,且对null/undefined安全。理解其源码分派逻辑与Object.entries()的差异后,你便能在"追求原生性能"与"保持 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
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考