
本文详解如何编写一个纯递归函数,将具有 main 和 offhand 两个顶层键的嵌套对象,分别提取其全部字符串(或原始)值,合并为两个扁平数组,避免在递归中错误地重复初始化结果对象。
本文详解如何编写一个纯递归函数,将具有 `main` 和 `offhand` 两个顶层键的嵌套对象,分别提取其全部字符串(或原始)值,合并为两个扁平数组,避免在递归中错误地重复初始化结果对象。
在原始代码中,核心问题在于:每次递归调用都新建了 { fromMainHand: [], fromOffHand: [] } 对象,导致深层递归返回的是嵌套结构(如 {fromMainHand: ['x'], fromOffHand: ['x']}),而非原始值;而 .push(devider(value)) 实际向数组中推入了整个对象,而非字符串本身——这直接造成最终数组为空。
要正确实现,关键在于 “单次构建结果结构,递归只负责收集值”。推荐采用「分离职责 + 顶层驱动」策略:主函数 devider 仅处理顶层键(main/offhand),并为每个分支单独调用递归提取器;提取器 collectValues 则专注遍历任意嵌套对象,返回所有原始值的一维数组。
以下是优化后的完整实现:
/**
* 递归提取对象中所有原始值(string/number/boolean/null/undefined)
* @param {any} obj - 待遍历对象
* @returns {Array} 扁平化的原始值数组
*/
function collectValues(obj) {
// 基础情况:原始值直接返回单元素数组
if (obj === null || typeof obj !== 'object') {
return [obj];
}
// 递归情况:遍历所有属性值,合并子结果
const result = [];
for (const value of Object.values(obj)) {
result.push(...collectValues(value));
}
return result;
}
/**
* 主函数:按 main/offhand 分支提取并归类原始值
* @param {Object} obj - 输入对象,必须含 main 和 offhand 键
* @returns {Object} { fromMainHand: [...], fromOffHand: [...] }
*/
function devider(obj) {
if (!obj || typeof obj !== 'object') {
throw new Error('Input must be a valid object');
}
return {
fromMainHand: obj.main ? collectValues(obj.main) : [],
fromOffHand: obj.offhand ? collectValues(obj.offhand) : []
};
}
// ✅ 正确示例数据(修复了原题中重复 key 的语法错误)
const obj = {
main: {
value: { value: 'main value' },
anotherValue: 'some another value'
},
offhand: {
value: {
value: 'offhand value',
anotherValue: 'again recursion'
}
}
};
console.log(devider(obj));
// 输出:
// {
// fromMainHand: ['main value', 'some another value'],
// fromOffHand: ['offhand value', 'again recursion']
// }
✅ 关键改进说明:
-
collectValues是纯粹的递归提取器,不关心键名,只保证返回扁平数组; -
devider在顶层统一构造结果结构,避免递归中反复创建对象; - 支持所有原始类型(字符串、数字、布尔值等),而不仅限于字符串;
- 显式处理
null(typeof null === 'object'是 JS 历史陷阱); - 使用展开运算符
...collectValues(value)高效合并子数组,语义清晰。
⚠️ 注意事项:
- 若输入对象可能缺失
main或offhand键,代码已通过可选链逻辑(obj.main ? ... : [])提供健壮性; - 避免在递归中使用闭包变量累积结果(如
let temp = []),易因作用域混乱导致错误; - 不建议强行压缩为“单一递归函数”,职责分离更利于测试、复用与维护。
此方案兼顾简洁性、可读性与工程健壮性,是处理分支化嵌套数据提取的典型范式。











