ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

es-toolkit entriesIn 别名解析:深入 toPairsIn 的继承属性键值对转换实现

es-toolkit entriesIn 别名解析:深入 toPairsIn 的继承属性键值对转换实现 es-toolkit entriesIn 别名解析深入 toPairsIn 的继承属性键值对转换实现【免费下载链接】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-toolkitentriesIn是 es-toolkit 兼容层es-toolkit/compat中面向 Lodash 用户的别名函数它只是toPairsIn的一个重命名导出。本文以docs/ja/compat/reference/object/entriesIn.md为入口完整讲解其真实语义指向的toPairsIn如何将对象含原型链上的继承属性、Map、Set统一转换为[key, value]键值对数组并结合仓库源码剖析其底层实现、性能特性与推荐替代方案。读完后你将能准确判断何时该用entriesIn/toPairsIn以及为什么文档明确建议优先使用Object.entries或for...in。entriesIn 是什么一个纯别名导出在 es-toolkit 的兼容层中entriesIn没有任何独立实现。打开src/compat/object/entriesIn.ts可以看到它的全部源码只有一行export { toPairsIn as entriesIn } from ./toPairsIn.ts;也就是说entriesIn toPairsIn两者是完全相同的函数对象。这一点在官方文档中被描述为entriesInはtoPairsInのエイリアス别名并在测试src/compat/object/entriesIn.spec.ts中被直接验证import { describe, expect, it } from vitest; import { entriesIn } from ./entriesIn; import { toPairsIn } from ./toPairsIn; describe(entriesIn, () { it(should be an alias of toPairsIn, () { expect(entriesIn).toBe(toPairsIn); }); });该测试断言两个函数引用严格相等toBe从测试层面锁定了别名关系。在公共入口src/compat/compat.ts中两个名字都被导出第 161 行导出entriesIn第 195 行导出toPairsIn因此从es-toolkit/compat导入任意一个名字均可获得同一功能。注Lodash 同时提供_.entriesIn与_.toPairsIn两个名字es-toolkit 的 compat 层为了保持这一 API 兼容性将entriesIn作为别名保留。toPairsIn 的核心能力包含继承属性的键值对转换toPairsIn的作用是将对象转换为键值对数组与toPairs的关键区别在于原型链上的可枚举属性也会被包含进来。基本对象转换import { toPairsIn } from es-toolkit/compat; const object { a: 1, b: 2 }; toPairsIn(object); // [[a, 1], [b, 2]]包含继承属性function Parent() { this.inherited value; } Parent.prototype.proto property; const child new Parent(); child.own own; toPairsIn(child); // [[inherited, value], [own, own], [proto, property]]可以看到实例自身的属性inherited、own和原型上的属性proto都被收集到结果数组中。这正是In后缀系列函数如keysIn、valuesIn、forIn的共性语义遍历会沿着原型链向上走。Map 与 Set 的转换除普通对象外toPairsIn还支持Map和Set// Map 转换保持键值对应关系 const map new Map([ [key1, value1], [key2, value2], ]); toPairsIn(map); // [[key1, value1], [key2, value2]] // Set 转换每个元素映射为 [value, value] const set new Set([1, 2, 3]); toPairsIn(set); // [[1, 1], [2, 2], [3, 3]]对于Set由于集合元素本身没有键结果数组中每个元素被展开为[value, value]形式如1变成[1, 1]这一行为与 Lodash 保持一致。参数与返回值项说明参数object要转换的对象、Map或Setobject类型返回值Array[string, any]键值对数组含继承属性源码级实现解析三层分发与两条快路径toPairsIn的完整实现在src/compat/object/toPairsIn.ts。从源码结构看其实现分为三个阶段export function toPairsInT( object?: Recordstring, T | Recordnumber, T | object ): Array[string, T] | Array[string, any] { // 1. null/undefined 兜底 if (object null) { return []; } // 2. Set / Map 快路径 if (object instanceof Set) { return setToEntries(object); } if (object instanceof Map) { return mapToEntries(object); } // 3. 普通对象路径先取 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; }边界兜底空值返回空数组object null即null或undefined时直接返回[]对应测试should return empty array when object is undefined。Set / Map 快路径Set和Map走专用内部工具避免了for...in遍历src/compat/_internal/setToEntries.ts通过set.values()迭代器逐一取出元素每个元素包装为[value, value]预先分配new Array(set.size)长度。src/compat/_internal/mapToEntries.ts同时取map.keys()与map.values()两个迭代器同步推进生成[key, value]数组。两条路径都采用先分配定长数组、再按下标填充的写法避免了push的重复扩容。普通对象路径keysIn 是关键普通对象先调用keysIn拿到含继承属性的键列表再逐键读取值。而keysIn见src/compat/object/keysIn.ts本身就是 compat 层中一个较重的函数其内部逻辑包括for...in收集键keysInImpl用for (const key in object)遍历天然包含原型链上的可枚举属性这正是toPairsIn能含继承属性的根本来源类数组对象特判isArrayLike时走arrayLikeKeysIn用times(length)生成0..n-1索引键并对稀疏数组做Object.hasOwn过滤原型对象特判isPrototype时排除constructor键Buffer / TypedArray 兼容分别补充offset、parent与buffer、byteLength、byteOffset等非索引可枚举属性为兼容旧环境行为而保留原始值装箱typeof不是object/function时执行Object(object)装箱后再遍历。这也解释了toPairsIn文档中的警告为了兼容 Lodash 的各种边界行为继承属性、类数组、原型对象、Map/Set内部逻辑复杂运行速度明显慢于原生方案。与 toPairs、Object.entries 的对比函数包含继承属性支持 Map/Set性能toPairs否仅自有可枚举属性是较慢复杂逻辑toPairsInentriesIn是含原型链是较慢逻辑更复杂Object.entries()否否快原生实现for...in循环是否快toPairsIn与toPairs的差异仅在是否包含继承属性前者基于keysIn含原型链后者基于keys仅自有键。如果你只需要对象自身的可枚举属性toPairs或原生Object.entries()即可满足只有明确需要遍历原型链属性时toPairsIn才有用武之地。性能警告与官方推荐替代方案官方文档在docs/compat/reference/object/toPairsIn.md开篇就放置了醒目警告日文版见docs/ja/compat/reference/object/toPairsIn.mdtoPairsIn函数因处理继承属性、Map与Set等复杂逻辑而运行缓慢。请改用更快、更现代的Object.entries()若确实需要继承属性请使用for...in循环。结合源码可以看出这份警告是实事求是的一次toPairsIn调用会依次经历instanceof Set/instanceof Map判断、keysIn内部的isArrayLike/isPrototype判断与for...in遍历、再逐键取值组装结果比原生Object.entries()多出数个层次的判断与临时对象分配。因此实际使用建议是只需要自有可枚举属性直接用Object.entries(obj)或用toPairs确实需要原型链上的属性优先手写for...in循环自行收集把要不要constructor、要不要做类型特判的控制权握在自己手里输入是Map/Set且需要 Lodash 兼容语义此时toPairsIn或toPairs仍是便捷选择Map可用Array.from(map)替代Set的[value, value]语义则需要自行映射追求与 Lodash 完全一致的行为在迁移期使用entriesIn/toPairsIn保证行为对齐后续再逐步替换为原生 API。测试覆盖行为一致性的保障compat 层对toPairsIn的行为做了系统性验证测试位于src/compat/object/toPairsIn.spec.ts覆盖以下场景普通对象返回字符串键值对原型链上的继承属性被包含Foo.prototype.b 2后toPairsIn(new Foo())同时含[a, 1]与[b, 2]含length属性的对象正常转换{ 0: a, 1: b, length: 2 }→ 三组键值对Map转换保持键值对应Set转换生成[value, value]字符串输入含Object(xo)装箱后的字符串按索引拆分为键值对undefined输入返回空数组。再加上entriesIn.spec.ts对别名关系的断言entriesIn/toPairsIn的语义在测试层面被完整锁定可作为迁移到 es-toolkit 时的行为基准。小结entriesIn是toPairsIn的纯别名二者是同一个函数从es-toolkit/compat导入任一名字结果一致toPairsIn将对象含原型链继承属性、Map、Set统一转为[key, value]数组Set元素映射为[value, value]底层实现基于keysIn的for...in遍历与mapToEntries/setToEntries两条快路径为兼容 Lodash 边界行为而牺牲了性能官方明确建议一般场景用Object.entries()需要继承属性时用for...in仅在需要 Lodash 完全兼容语义时使用本函数。【免费下载链接】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),仅供参考
返回列表