
本文讲解如何正确遍历 javascript 中的嵌套对象,提取每一项中特定键(如 `numberofdrinks`)的数值,并高效计算其总和,避免常见索引错误。
在处理类似 { 'Alice': { count: 5 }, 'Bob': { count: 3 } } 这样的键值对结构时,一个典型误区是混淆了 Object.values() 返回的值对象数组与原始对象的键名关系。例如,原代码中:
const drunks = {
'Cheryl': { numberOfDrinks: 10 },
'Jeremy': { numberOfDrinks: 4 },
'Gordon': { numberOfDrinks: 2 },
'Laura': { numberOfDrinks: 6 }
};
let totalDrunks = 0;
let numberOfDrunks = Object.values(drunks); // → [{numberOfDrinks:10}, {numberOfDrinks:4}, ...]
numberOfDrunks.forEach((drink) => {
totalDrunks += drunks[drink]; // ❌ 错误!drink 是对象,不能作为 drunks 的 key
});此处 drink 是一个对象(如 { numberOfDrinks: 10 }),而 drunks[drink] 实际上等价于 drunks[Object.prototype.toString.call(drink)],结果为 undefined,导致累加失败(最终 totalDrunks 为 NaN)。
✅ 正确做法是:直接访问当前值对象上的目标属性:
numberOfDrunks.forEach((drink) => {
totalDrunks += drink.numberOfDrinks; // ✅ 正确:从每个 value 对象中取属性
});
console.log(totalDrunks); // 22更简洁、函数式风格的写法推荐使用 reduce:
const totalDrunks = Object.values(drunks) .reduce((sum, person) => sum + person.numberOfDrinks, 0); console.log(totalDrunks); // 22
⚠️ 注意事项:
- 确保每个嵌套对象都存在目标属性(如 numberOfDrinks),否则需添加安全访问逻辑(如 person?.numberOfDrinks ?? 0);
- 若对象结构更深(如 person.stats?.drinks?.count),建议结合可选链(?.)与空值合并(??)操作符提升健壮性;
- 避免用 for...in 配合 hasOwnProperty——虽可行,但 Object.values() + 数组方法更语义清晰、性能更优。
总结:遍历嵌套对象求和的核心在于明确数据层级——Object.values() 提供的是“值的集合”,而非“键的集合”,应直接操作这些值对象本身,而非试图反向用它们去索引原对象。










