JavaScript递归查找嵌套对象数组按ID匹配返回undefined问题
问题原因
你能在控制台打印出匹配id=10的项,但赋值拿不到结果,是三个逻辑错误导致的:
- 递归遍历children子节点时,你调用了
searchNavItems(child)但没有接收返回值,也没有在找到匹配项时把结果逐层return出去,子层级找到的结果直接被丢弃,上层函数拿不到值 - 处理子节点的分支没有写return语句,JS函数没有显式return时默认返回
undefined - 外层遍历
data.navItems用了forEach方法,forEach设计上就没有返回值,你把它的执行结果赋值给dataItem,得到的永远是undefined
修复后的实现
直接替换对应代码即可:
const searchNavItems = (navItem, targetId) => { // 当前节点匹配直接返回 if (navItem.id === targetId) { return navItem; } // 有子节点就递归遍历 if (navItem.type === "directory" && navItem.hasOwnProperty("children") && navItem.children.length > 0) { for (const child of navItem.children) { const res = searchNavItems(child, targetId); // 找到结果就立刻返回,终止后续遍历 if (res) return res; } } // 当前分支没找到返回false return false; }; // 遍历顶层navItems找目标,不要用forEach接返回值 let dataItem = null; const targetId = 10; for (const item of data.navItems) { const findRes = searchNavItems(item, targetId); if (findRes) { dataItem = findRes; break; } } console.log(dataItem); // 会正确输出id=10的文件对象
关键注意点
写递归查找逻辑的时候一定要记住:
- 每一层递归的返回值都要接住,一旦找到目标要沿着调用链逐层return出去,不能只在最内层匹配的时候return
- 不要用
forEach/map这类遍历方法做查找终止,这类方法即便你在回调里return也不会打断整个遍历,用普通for循环找到就break/return性能更好 - 不要把遍历方法自身的返回值当成查找结果,
forEach永远返回undefined,map返回的是和原数组等长的新数组,都不适合做查找场景
内容的提问来源于stack exchange,提问作者Ancesteral
相关产品推荐
相关产品推荐

