
本文详解如何正确统计 JSON 对象中某个键(如 __metadata 或 ItemToEkbeNav)所对应值的键值对数量,并区分根级结构与原始类型,避免对字符串误用 Object.keys() 导致错误结果。
本文详解如何正确统计 json 对象中某个键(如 `__metadata` 或 `itemtoekbenav`)所对应值的键值对数量,并区分根级结构与原始类型,避免对字符串误用 `object.keys()` 导致错误结果。
在处理嵌套 JSON 数据(尤其是 OData 响应)时,开发者常需判断某字段是否为“对象型根节点”——即其值本身是一个包含多个键值对的对象(如 __metadata),而非简单字符串(如 "Ebeln": "5200000719")或空结构。直接对字符串调用 Object.keys('Ebeln') 会将字符串视为类数组对象,返回长度为字符串字符数(如 'Ebeln'.length === 5),这显然不是我们想要的“键值对数量”。
✅ 正确做法是:先校验数据类型,再安全提取键数量。核心逻辑如下:
- 若目标值为 null 或 undefined → 键数为 0;
- 若目标值为 object 且非 Array → 使用 Object.keys(value).length;
- 若目标值为 string、number、boolean 等原始类型 → 键数为 0(因其无内部键值结构);
- 若目标值为 Array → 可选择返回数组长度(表示子项数量),但注意:数组本身不是“键值对集合”,若需统计每个数组元素的键数,需遍历处理。
以下为健壮的工具函数示例:
function countKeys(obj, key) {
if (!obj || typeof obj !== 'object') return 0;
const value = obj[key];
if (value == null) return 0;
if (typeof value === 'object' && !Array.isArray(value)) {
return Object.keys(value).length;
}
return 0; // 字符串、数字等原始类型不贡献键值对
}
// 示例使用
const data = {
results: [{
"__metadata": { "id": "", "uri": "", "type": "YGW" },
"Ebeln": "5200000719",
"ItemToEkbeNav": { "__deferred": { "uri": "https:" } }
}]
};
const item = data.results[0];
console.log(countKeys(item, "__metadata")); // → 3
console.log(countKeys(item, "Ebeln")); // → 0 (字符串,非对象)
console.log(countKeys(item, "ItemToEkbeNav")); // → 1 (含 "__deferred")⚠️ 注意事项:
- Object.keys() 仅适用于普通对象,对 null、undefined、原始类型会抛错或返回意外结果,务必前置类型判断;
- ItemToEkbeNav 是根级键(key),其值 { "__deferred": {...} } 才是待统计的子对象——因此判断“是否为根元素”本质是确认该键存在于当前对象层级,且其值为非 null 对象;
- 实际项目中建议配合 TypeScript 类型守卫(如 isPlainObject())或 Lodash 的 _.isPlainObject() 提升鲁棒性;
- 若需递归统计所有嵌套层级的键总数,应改用深度遍历算法,而非单层 Object.keys()。
掌握这一模式,即可精准解析任意 JSON 结构中的对象层级关系,为动态表单渲染、元数据校验、API 响应适配等场景提供可靠基础。


















