es-toolkit valuesIn 兼容 API 详解:遍历对象自身与原型链上所有属性值
2026/9/16 13:31:34 网站建设 项目流程

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]>;

参数

  • objectany):要查询属性值的对象。

返回值

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决定,二者是配套实现(valuesInkeysIn的对应关系,可参照 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.prototypeParent.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 的处理

nullundefinedvaluesIn返回空数组,不会抛错:

import { valuesIn } from 'es-toolkit/compat'; valuesIn(null); // [] valuesIn(undefined); // []

该行为由keysIn的入口守卫保证(keysIn.ts):

export function keysIn(object?: any): string[] { if (object == null) { return []; } ... }

底层实现与关键分支

keysInvaluesIn的键名来源,其内部针对不同输入类型做了分支处理(keysIn.ts),理解这些分支有助于预测valuesIn的输出:

  • 对象或函数:进一步区分是否为类数组、是否为原型对象(isPrototype),分别走不同路径;
  • 非对象(原始值):先通过Object(object)装箱后再收集键;
  • null / undefined:直接返回空数组。

值得注意的三个细节分支:

  1. 类数组对象按数组处理arrayLikeKeysIn会先按length生成索引键,再补充继承的额外键(keysIn.ts)。因此对{ 0: 'a', 1: 'b', length: 2 }这类带length的对象,valuesIn会返回['a', 'b', 2](键序中包含length的值),对应测试 valuesIn.spec.ts。

  2. 稀疏数组按稠密数组处理:缺失的索引会被补齐(用times生成全部索引),保证与 lodash 行为一致。

  3. 排除constructor:当遍历到原型对象本身(如Object.prototype)时,会过滤掉constructor键(keysIn.ts),这就是文档示例中"constructor excluded"注释的由来。

另外,arrayLikeKeysIn还为特殊宿主对象做了兼容:Node.js 的 Buffer 会补充offsetparent键,TypedArray 会补充bufferbyteLengthbyteOffset键(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
  • 若只是需要与 lodashvalues语义对齐(不含继承属性),应改用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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询