JavaScript递归计算嵌套对象薪资总和函数逻辑解析
递归薪资求和函数工作原理解析
递归调用位置的合理性说明
这个函数处理的嵌套部门结构只有两类节点,逻辑边界非常清晰:
- 叶子节点:存储员工信息的数组,没有下一级子部门,是递归的终止位置
- 分支节点:存储子部门的普通对象,必须遍历完名下所有子部门的薪资,才能算出当前部门的总薪资
标注为line*的位置,恰好是分支节点处理逻辑中遍历到每一个直接子部门的节点位置,只有在这里调用递归,才能逐个拿到每个子部门的薪资总和,再逐层向上累加。放在其他位置都会直接导致逻辑失效:
- 如果放在数组判断的分支(case1)里:数组本身就是递归终止点,里面存的是单个员工数据,不存在下一级子部门,在这里递归会传入单个员工对象,要么计算结果错误,要么直接触发死循环。
- 如果放在case2分支的for循环外面:不管是在循环启动前还是循环结束后,要么还没拿到当前部门下的子部门列表,只能反复把当前部门本身传入递归造成死循环;要么循环执行阶段没有累加子部门的薪资结果,sum从头到尾都是0,返回值完全错误。
函数完整执行流程
我们以最常见的调用sumSalaries(company)为例,整个执行是典型的深度优先遍历过程,逐层向下钻取直到碰到叶子节点,再把结果逐层向上累加,具体步骤如下:
- 首次调用传入顶层company对象,判断入参不是数组,进入分支处理逻辑,初始化当前层级sum为0,通过
Object.values(company)拿到两个直接子节点:对应销售部的sales员工数组、对应研发部的development部门对象。 - 遍历第一个子节点
sales数组,递归调用sumSalaries(sales):- 判断入参是数组,进入终止逻辑,用
reduce累加数组内所有员工的薪资:1000 + 1600 = 2600,直接返回2600 - 顶层sum累加这个返回值,当前sum = 0 + 2600 = 2600
- 判断入参是数组,进入终止逻辑,用
- 遍历第二个子节点
development对象,递归调用sumSalaries(development):- 判断入参不是数组,进入分支处理逻辑,初始化当前层级sum为0,通过
Object.values(development)拿到两个直接子节点:对应站点组的sites员工数组、对应内部支持组的internals员工数组 - 遍历第一个子节点
sites数组,递归调用sumSalaries(sites):判断是数组,reduce累加得2000 + 1800 = 3800,返回3800,研发部层级的sum更新为0 + 3800 = 3800 - 遍历第二个子节点
internals数组,递归调用sumSalaries(internals):判断是数组,reduce累加得1300,返回1300,研发部层级的sum更新为3800 + 1300 = 5100 - 研发部层级循环结束,返回sum值5100给顶层调用
- 判断入参不是数组,进入分支处理逻辑,初始化当前层级sum为0,通过
- 顶层sum累加研发部返回的5100,当前sum = 2600 + 5100 = 7700
- 顶层循环结束,返回最终结果7700,也就是全公司的总薪资。
内容的提问来源于stack exchange,提问作者Emmanuel C. O Peters
相关产品推荐
相关产品推荐

