JavaScript如何深度修改对象数组中的属性值?
如何深度修改嵌套对象数组中的selected属性?
你遇到的问题其实就是典型的递归遍历嵌套结构场景——原来的代码只处理了两层节点,没考虑更深的嵌套。既然你已经在用Lodash,刚好可以用它提供的工具函数来优雅解决这个问题,不用手动写多层嵌套的map逻辑。
方法一:使用Lodash的_.cloneDeepWith(推荐,贴合你的技术栈)
_.cloneDeepWith是Lodash专门用来自定义深克隆逻辑的函数,它会自动递归遍历整个对象结构,对每个遍历到的元素执行你指定的回调函数,完美适配你的需求:
function clearAllSelected() { const updatedContent = _.cloneDeepWith(content, (node) => { // 判断当前遍历的是一个包含selected属性的节点对象 if (typeof node === 'object' && node !== null && 'selected' in node) { // 将该节点的selected设为false node.selected = false; // 返回undefined,让Lodash继续递归处理该节点的子属性(比如childNodes) return undefined; } }); setContent(updatedContent); setActive(null); }
为什么这个方法有效?
- 它会自动遍历所有嵌套层级的节点,不管你的
childNodes嵌套多少层都能覆盖 - 回调函数对每个节点生效,统一修改
selected属性 - 返回
undefined的作用是告诉Lodash:继续按默认逻辑克隆当前节点的子属性(比如childNodes),不会中断递归
方法二:纯JavaScript递归函数(不依赖Lodash)
如果你想脱离Lodash实现,也可以写一个简单的递归函数来处理每个节点及其子节点:
// 递归处理单个节点及其所有子节点 function resetNodeSelected(node) { // 复制当前节点,避免直接修改原state const newNode = {...node}; // 重置当前节点的selected状态 newNode.selected = false; // 如果有子节点,递归处理每个子节点 if (newNode.childNodes && newNode.childNodes.length > 0) { newNode.childNodes = newNode.childNodes.map(resetNodeSelected); } return newNode; } // 主函数:遍历顶层节点,批量处理 function clearAllSelected() { const updatedContent = content.map(resetNodeSelected); setContent(updatedContent); setActive(null); }
这个方法的逻辑:
resetNodeSelected函数负责单个节点的处理:先复制节点,修改selected,再递归处理它的childNodes- 主函数通过
map遍历所有顶层节点,调用递归函数就能覆盖所有嵌套层级的节点
对比你原来的代码
你原来的代码只手动处理了第一层子节点,而上面两种方法都是递归遍历所有嵌套层级,不管你的节点嵌套多少层,都能把所有selected属性统一设为false。
内容的提问来源于stack exchange,提问作者ask4you
相关产品推荐
相关产品推荐

