es-toolkit valuesIn 兼容 API 详解:遍历对象自身与原型链上所有属性值
【免费下载链接】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
导读
valuesIn是 es-toolkit 为兼容 lodash 而提供的对象工具函数,它返回对象所有可枚举字符串键属性的值,包括从原型链上继承的属性值。本篇文章围绕 docs/compat/reference/object/valuesIn.md 展开,结合 src/compat/object/valuesIn.ts 与 src/compat/object/keysIn.ts 的源码实现,说明其与原生Object.values的差异、适用场景与底层原理,帮助你在迁移 lodash 代码时正确选型。
使用警告:
valuesIn因需要遍历原型链属性,内部逻辑复杂、运行较慢。官方文档明确建议优先使用更快的原生Object.values。只有在确实需要包含继承属性时才应使用本函数。
函数签名与基本行为
valuesIn返回对象所有属性值组成的数组,包括继承的原型属性。
const values = valuesIn(obj);从 valuesIn.ts 可以看到,该函数提供了两组 TypeScript 重载签名,兼顾了泛型对象与数组/类数组对象两种调用场景:
export function valuesIn<T>(object: Record<string, T> | Record<number, T> | ArrayLike<T> | null | undefined): T[]; export function valuesIn<T extends object>(object: T | null | undefined): Array<T[keyof T]>;参数
object(any):要查询属性值的对象。
返回值
(any[]):包含对象所有属性值的数组,包含继承的原型属性值。
基本用法
普通对象与数组
与Object.values最直观的区别在于:valuesIn能识别并处理数组与类数组对象,并且会包含原型链上的属性值。
import { valuesIn } from 'es-toolkit/compat'; const obj = { a: 1, b: 2, c: 3 }; valuesIn(obj); // [1, 2, 3] // 同样支持数组 valuesIn([1, 2, 3]); // [1, 2, 3]这一点在源码中得到了印证:valuesIn先调用keysIn(object)取得全部键名,再逐个取值(valuesIn.ts):
export function valuesIn(object: any): any[] { const keys = keysIn(object); const result: any[] = new Array(keys.length); for (let i = 0; i < keys.length; i++) { const key = keys[i]; result[i] = object[key]; } return result; }也就是说,valuesIn的输出键序完全由keysIn决定,二者是配套实现(valuesIn与keysIn的对应关系,可参照 compat 入口 compat.ts 中相邻的导出声明)。
包含原型链继承的属性值
这是valuesIn区别于Object.values的核心能力:
import { valuesIn } from 'es-toolkit/compat'; function Parent() { this.a = 1; } Parent.prototype.inherited = 'fromParent'; function Child() { Parent.call(this); this.b = 2; } Child.prototype = Object.create(Parent.prototype); Child.prototype.childProp = 'childValue'; const obj = new Child(); valuesIn(obj); // [1, 2, 'childValue', 'fromParent'](constructor 被排除)上述结果中的'childValue'与'fromParent'分别来自Child.prototype与Parent.prototype,这正是"In"后缀的含义——遍历范围覆盖整个原型链。对应测试见 valuesIn.spec.ts:
it(`should include inherited string keyed property values`, () => { function Foo(this: any) { this.a = 1; } Foo.prototype.b = 2; const expected = [1, 2]; const actual = valuesIn(new Foo()).sort(); expect(actual).toEqual(expected); });null 与 undefined 的处理
对null或undefined,valuesIn返回空数组,不会抛错:
import { valuesIn } from 'es-toolkit/compat'; valuesIn(null); // [] valuesIn(undefined); // []该行为由keysIn的入口守卫保证(keysIn.ts):
export function keysIn(object?: any): string[] { if (object == null) { return []; } ... }底层实现与关键分支
keysIn是valuesIn的键名来源,其内部针对不同输入类型做了分支处理(keysIn.ts),理解这些分支有助于预测valuesIn的输出:
- 对象或函数:进一步区分是否为类数组、是否为原型对象(
isPrototype),分别走不同路径; - 非对象(原始值):先通过
Object(object)装箱后再收集键; - null / undefined:直接返回空数组。
值得注意的三个细节分支:
类数组对象按数组处理:
arrayLikeKeysIn会先按length生成索引键,再补充继承的额外键(keysIn.ts)。因此对{ 0: 'a', 1: 'b', length: 2 }这类带length的对象,valuesIn会返回['a', 'b', 2](键序中包含length的值),对应测试 valuesIn.spec.ts。稀疏数组按稠密数组处理:缺失的索引会被补齐(用
times生成全部索引),保证与 lodash 行为一致。排除
constructor:当遍历到原型对象本身(如Object.prototype)时,会过滤掉constructor键(keysIn.ts),这就是文档示例中"constructor excluded"注释的由来。
另外,arrayLikeKeysIn还为特殊宿主对象做了兼容:Node.js 的 Buffer 会补充offset、parent键,TypedArray 会补充buffer、byteLength、byteOffset键(keysIn.ts),避免遗漏这些运行环境特有的可枚举属性。
与原生 Object.values、values 的对比选型
| 场景 | 推荐 API | 说明 |
|---|---|---|
| 只取自身可枚举属性值 | Object.values | 原生方法,性能最佳 |
| 需包含原型链继承属性值 | valuesIn | 本兼容函数,性能较慢 |
与 lodashvalues对齐 | values(compat) | 只取自身属性,参考values文档 |
es-toolkit 官方在文档开头给出了明确的性能警告:valuesIn因处理原型属性的复杂逻辑而运行缓慢,应优先使用更快的Object.values。因此建议:
- 新代码一律使用原生
Object.values; - 迁移 lodash 遗留代码且确实依赖原型链属性时,才用
es-toolkit/compat下的valuesIn; - 若只是需要与 lodash
values语义对齐(不含继承属性),应改用values。
小结
valuesIn返回对象所有可枚举字符串键属性的值,包含原型链继承的属性值;- 对
null/undefined返回[],对数组、类数组、稀疏数组均有 lodash 一致的兼容处理; - 实现上委托给
keysIn获取键名再取值,constructor会被排除; - 官方明确提示性能较慢,能用
Object.values时请优先使用原生方法。
相关参考:实现源码 valuesIn.ts、键名实现 keysIn.ts、测试用例 valuesIn.spec.ts、兼容入口导出 compat.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),仅供参考