You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:52:39