
本文详解如何用递归方式安全、高效地遍历任意深度嵌套的数组与对象结构,并累加其中所有数字值,提供带累加器变量和无额外变量两种实现方案,并规避栈溢出风险。
本文详解如何用递归方式安全、高效地遍历任意深度嵌套的数组与对象结构,并累加其中所有数字值,提供带累加器变量和无额外变量两种实现方案,并规避栈溢出风险。
在处理如 { number: [{ number: 3 }, { number: [{ number: 5 }] }] } 这类高度嵌套的数据时,原始代码因错误的递归终止逻辑与自引用调用(如 return numbers + getSumOfNumbers(numbers))导致无限递归,最终触发栈溢出。核心问题在于:未正确区分「递归入口」与「基础值返回」,且未对非数字/非对象/非数组类型(如 null、undefined)做防御性处理。
以下是两种专业、健壮的解决方案:
✅ 方案一:无额外变量(推荐 —— 函数式风格)
采用纯递归 + reduce 组合,语义清晰、无副作用:
const getSumOfNumbers = (data) => {
if (typeof data === 'number') return data; // 基础情况:直接返回数字
if (Array.isArray(data)) // 数组:递归求和每个元素
return data.reduce((sum, item) => sum + getSumOfNumbers(item), 0);
if (typeof data === 'object' && data !== null) // 非空对象:递归求和所有属性值
return Object.values(data).reduce((sum, value) => sum + getSumOfNumbers(value), 0);
return 0; // null、undefined、string、boolean 等非数字类型均贡献 0
};? 关键设计点:
- 使用
Object.values()统一处理对象属性,避免手动for...in循环及原型污染风险;- 显式检查
data !== null,因typeof null === 'object'是 JavaScript 的历史陷阱;- 所有分支均有明确返回值,杜绝
undefined参与算术运算(否则NaN污染结果)。
✅ 方案二:使用累加器变量(显式状态管理)
适用于需调试中间过程或兼容旧环境的场景,通过参数传递累加器:
const getSumOfNumbersWithAcc = (data, acc = 0) => {
if (typeof data === 'number') return acc + data;
if (Array.isArray(data)) {
for (const item of data) {
acc = getSumOfNumbersWithAcc(item, acc); // 更新累加器并继续递归
}
return acc;
}
if (typeof data === 'object' && data !== null) {
for (const value of Object.values(data)) {
acc = getSumOfNumbersWithAcc(value, acc);
}
return acc;
}
return acc; // 忽略非数字/非结构类型
};⚠️ 注意事项:
- 切勿在递归中修改外部变量(如闭包中的
let sum = 0),否则多层调用会相互干扰;- 必须将更新后的
acc作为返回值层层向上透传,确保状态一致性。
? 测试验证(覆盖边界情况)
const numbers = [
{ number: [{ number: 3 }, { number: [{ number: 5 }] }] },
{ number: 8 },
5,
[1, 2, [3, 4]],
{ a: 1, b: 2, c: { d: 3, e: 4 } },
null,
[],
{}
];
console.log(getSumOfNumbers(numbers)); // 输出:31(3+5+8+5+1+2+3+4+1+2+3+4 = 31)✅ 总结
-
根本规避栈溢出:确保每次递归都向更小的子结构推进(数组元素 / 对象值),且存在明确终止条件(
number类型); -
鲁棒性优先:始终校验
null、类型有效性,拒绝隐式类型转换; - 可读性与可维护性:方案一更符合现代 JavaScript 实践;方案二便于插入日志或断点调试;
- 性能提示:对于超深嵌套(>1000 层),可考虑转为迭代(栈模拟),但本例数据结构下递归完全安全。
掌握这两种模式,即可从容应对 JSON-like 数据的任意嵌套求和需求。

















