Angular TypeScript递归嵌套元素报栈溢出错误如何解决
问题根因
你的代码触发栈溢出、输出不符合预期,一共有3处核心问题:
splice用法错误:Array.splice()会原地修改调用它的数组,返回值是被删除元素构成的新数组。你写了tokens = tokens.splice(0, 1),相当于每次递归都把tokens重置为长度1的数组(仅包含当前取出的token),递归终止条件tokens.length > 0永远成立,最终触发无限递归栈溢出。- 方法名拼写错误:你定义的方法名是
initNode,递归调用时写成了initNodes(多了末尾的s),会导致调用逻辑不符合预期。 - 叶子节点结构错误:你无条件给子节点包了一层数组,当递归到tokens为空返回null时,最后一层节点的children会变成
[null],和你预期的children: null不符。
修正方案
首先先明确节点的TS类型定义:
interface Node { name: string; children: Node[] | null; }
修正递归方法,不需要重新赋值splice/shift的返回值给原数组,同时单独处理叶子节点的children值:
private initNode(tokens: string[]): Node | null { // 无剩余token时终止递归,返回null if (!tokens?.length) { return null; } // 取出队首token,shift会原地修改数组,直接调用即可 const currentName = tokens.shift(); const child = this.initNode(tokens); return { name: currentName, // 存在子节点时包入数组,无节点时直接赋值null children: child ? [child] : null }; }
调用方法时,因为shift/splice会修改传入的数组,如果不想污染原始的tokens数组,建议传入副本,最终把返回的根节点包入数组即可得到目标结构:
const tokens: string[] = ['A', 'B', 'C']; // 传入数组副本避免修改原输入 const root = this.initNode([...tokens]); const result = root ? [root] : [];
执行后result的结构和你给出的预期输出完全一致。
内容的提问来源于stack exchange,提问作者LukyFoggy
相关产品推荐
相关产品推荐

