如何用JavaScript为JSON对象指定节点添加嵌套子数组并解决相关报错?
解决方案:动态给JSON对象添加子数组
我来帮你梳理下问题所在,然后给出更可靠的解决方案。你的核心需求是从原始JSON数据中提取子节点,动态添加到另一个结构对应的节点下,但之前的代码里有几个关键问题导致报错和不符合预期:
你代码里的主要问题
- 用字符串拼接生成JSON对象:这种方式很容易出现语法错误(比如引号转义、多余逗号),而且完全没必要——直接操作JavaScript对象要安全得多。
- 错误地将字符串存入子数组:在
traverse函数里,你把'{"name": "'+j.name+'"}'这种字符串push到child_array,最后赋值给d.children,这会导致children是字符串数组,而不是预期的JSON对象数组,后续操作自然会报错。 - 队列遍历逻辑有缺陷:初始时
queue是空数组,你直接访问queue[0].name会抛出Cannot read properties of undefined的异常,这就是你遇到push()报错的原因之一。
修正后的实现方案
我们可以通过直接操作JS对象来避免字符串拼接的问题,同时用更清晰的递归查找来定位目标节点:
1. 重构twoLevelSelection函数
直接创建新的对象结构,不用字符串拼接:
function twoLevelSelection(json) { // 复制根节点名称,为每个子节点初始化空children数组 return { name: json.name, children: json.children.map(child => ({ name: child.name, children: [] })) }; }
2. 修正traverse函数
用递归方式在原始数据中找到目标节点,然后将子节点复制到目标结构中:
// originalData: 原始的flare数据 // targetNode: 从updatedJson中找到的需要添加子节点的目标节点 function traverse(originalData, targetNode) { // 递归查找原始数据中对应名称的节点 function findTargetNode(data, targetName) { if (data.name === targetName) { return data; } // 遍历子节点继续查找 if (data.children) { for (const child of data.children) { const found = findTargetNode(child, targetName); if (found) return found; } } return null; } // 找到原始数据中的对应节点 const originalTarget = findTargetNode(originalData, targetNode.name); if (originalTarget && originalTarget.children) { // 将原始节点的子数组复制到目标节点(用扩展运算符做浅拷贝,避免引用问题) targetNode.children = [...originalTarget.children]; } }
3. 使用示例
// 原始数据 const flare = { "name": "Root", "children": [ { "name": "child1", "children": [{"name": "child11"}, {"name": "child12"}] }, { "name": "child2", "children": [{"name": "child21"}, {"name": "child22"}] } ] }; // 生成初始的updatedJson结构(每个子节点带空children) let updatedJson = twoLevelSelection(flare); // 假设点击的是child1,从updatedJson中找到这个节点 const clickedNode = updatedJson.children.find(child => child.name === "child1"); // 调用traverse添加子节点 traverse(flare, clickedNode); // 查看最终结果 console.log(updatedJson);
运行这段代码后,updatedJson会变成你想要的结构:
{ "name": "Root", "children": [ {"name": "child1", "children": [{"name": "child11"}, {"name": "child12"}]}, {"name": "child2", "children": []} ] }
额外说明
- 如果需要给
child2也添加子节点,只需要找到updatedJson.children中对应的节点,再调用一次traverse即可。 - 如果你的数据层级更深,可以保持递归查找的逻辑,它能适配任意深度的节点查找。
内容的提问来源于stack exchange,提问作者Kaustav Roy
相关产品推荐
相关产品推荐

