Object.values无法穿透多级嵌套,需结合递归、字段白名单或路径匹配提取业务核心原始数据;须先明确目标字段(如id、name、price),排除非业务字段,并防范null、循环引用等陷阱。

直接用 Object.values 无法自动穿透多级嵌套——它只取第一层属性值。要提取深层的业务核心原始数据(比如所有 id、name、price 等字段组成的数组),需要配合递归或扁平化逻辑,而不是单靠 Object.values 一把梭。
明确“业务核心原始数据”指什么
先别急着写代码,花10秒确认:你真正要的是哪些字段?例如:
- 所有商品的
sku和price(不是整个商品对象) - 所有用户的
id、mobile、status - 排除掉
metadata、__cache、children等非业务字段
这个界定决定后续过滤逻辑,否则容易提取出大量冗余或无效数据。
用 Object.values + 递归遍历 + 字段白名单
适合结构不固定、层级深但目标字段名统一的场景(如所有叶子节点都有 id 和 name):
function extractCoreValues(obj, fields = ['id', 'name', 'price'], result = []) {
if (obj === null || typeof obj !== 'object') return result;
// 如果当前对象包含目标字段,且是原始值(非 object/array),就推入
fields.forEach(field => {
if (field in obj && obj[field] !== null && typeof obj[field] !== 'object') {
result.push(obj[field]);
}
});
// 递归处理所有子值
Object.values(obj).forEach(val => {
if (typeof val === 'object' && val !== null) {
extractCoreValues(val, fields, result);
}
});
return result;
}
// 示例
const data = {
shop: {
id: 101,
name: "旗舰店",
products: [
{ id: 1, name: "iPhone", price: 5999, meta: { tag: "hot" } },
{ id: 2, name: "AirPods", price: 1299 }
]
}
};
console.log(extractCoreValues(data));
// [101, "旗舰店", 1, "iPhone", 5999, 2, "AirPods", 1299]
更可控:路径匹配 + Object.values 配合 flatMap
当业务数据集中在特定路径(如 list、items、data.rows),推荐先定位再提值,避免误采:
- 用
Object.values快速拿到某一层的集合(如response.data.items) - 再用
flatMap或map提取每个项的指定字段 - 支持嵌套字段访问,比如
item.product.name
示例:
const getCoreArray = (obj, path, fields) => {
// 按点号路径取值,如 'data.items'
const getValueByPath = (o, p) => p.split('.').reduce((a, c) => a?.[c], o);
const target = getValueByPath(obj, path);
if (!Array.isArray(target)) return [];
return target.flatMap(item =>
fields.map(field => {
// 支持嵌套字段:'product.id' → item.product?.id
return field.split('.').reduce((a, c) => a?.[c], item);
})
).filter(v => v !== undefined && v !== null);
};
// 调用
getCoreArray(apiResponse, 'data.items', ['id', 'product.name', 'price']);
警惕陷阱:null、undefined、循环引用、Date/RegExp 等非纯对象
Object.values 对 null 报错,对 Date、RegExp、Map 返回空数组,对循环引用直接栈溢出。生产环境务必加防护:
- 用
if (obj && typeof obj === 'object' && !Array.isArray(obj))做前置判断 - 递归时用
WeakSet记录已访问对象,防循环 - 原始数据建议先用
JSON.parse(JSON.stringify(obj))脱敏(仅限无函数/undefined/循环的场景)
简单安全的兜底写法:
function safeValues(obj) {
try {
return obj && typeof obj === 'object' ? Object.values(obj) : [];
} catch {
return [];
}
}

















