JS中校验childId与parentId归属关系的函数修正问题
修复树形结构中子节点归属校验函数
checkParentId 原函数的问题分析
原函数逻辑完全偏离需求,核心错误点:
- 错误地将「当前节点id等于parentId」作为返回true的条件,完全未关联
childId的校验,导致像checkParentId(obj, 1, 2)这种本该返回false的场景错误返回true; - 递归调用时直接返回结果,若第一个子节点的递归返回false,会跳过后续兄弟节点的遍历;
return false写在循环内部,第一个节点不符合条件就直接终止遍历,无法检查后续节点。
修复后的代码
const obj = [ { id: 1, name: "parent 1", children: [ { id: 11, name: "child 1", children: [ { id: 12, name: "grand 1", children: [] } ] } ] }, { id: 2, name: "parent 2", children: [ { id: 21, name: "c1", children: [] } ] }, ]; const checkParentId = (tree, parentId, childId) => { // 遍历当前层级的所有节点 for (const item of tree) { // 找到目标父节点后,检查其整个子树是否包含目标子节点 if (item.id === parentId) { const hasChild = (node) => { // 当前节点就是目标子节点,直接返回true if (node.id === childId) return true; // 递归遍历所有子节点 for (const child of node.children) { if (hasChild(child)) return true; } return false; }; return hasChild(item); } // 当前节点不是父节点,递归检查它的子树 if (item.children.length > 0) { const result = checkParentId(item.children, parentId, childId); // 只有递归找到匹配才返回true,否则继续遍历当前层级其他节点 if (result) return true; } } // 所有节点遍历完毕仍无匹配,返回false return false; }; // 测试用例验证 console.log(checkParentId(obj, 1, 12)); // true console.log(checkParentId(obj, 1, 21)); // false console.log(checkParentId(obj, 1, 11)); // true console.log(checkParentId(obj, 2, 21)); // true console.log(checkParentId(obj, 1, 2)); // false
关键修改点
- 逻辑对齐需求:先定位
parentId对应的节点,再在其完整子树中递归查找childId,完全贴合「校验子节点归属」的核心需求; - 保证遍历完整性:将
return false移至循环外部,确保所有节点都被检查后才返回最终结果; - 递归结果合理处理:递归子节点时仅当找到匹配才终止遍历,否则继续检查当前层级的兄弟节点;
- 逻辑拆分清晰:用辅助函数
hasChild封装子树查找逻辑,代码可读性更强。
内容的提问来源于stack exchange,提问作者Sougata Mukherjee
相关产品推荐
相关产品推荐

