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

如何编写函数动态修改嵌套对象指定路径的属性值并返回完整对象?

动态修改嵌套对象指定属性的解决方案

我来帮你搞定这个动态修改嵌套对象的问题~之前用reduce没达到预期效果,大概率是没处理好路径的最后一步或者拷贝逻辑,下面给你两种实用的解决方案,按需选择:

方案一:原地修改原对象(高效直接)

如果不需要保留原对象的初始状态,直接修改原对象是最省事的方式。我们只需要顺着路径找到要修改属性的父节点,然后直接修改对应的值即可:

function updateObject(value, path, obj) {
  // 找到路径倒数第二个节点(目标属性的父节点)
  const parentNode = path.slice(0, -1).reduce((current, key) => {
    return current[key];
  }, obj);
  // 获取路径最后一个键(要修改的属性/索引)
  const finalKey = path[path.length - 1];
  // 修改父节点的对应属性
  parentNode[finalKey] = value;
  // 返回修改后的原对象
  return obj;
}

// 测试用例
let garages = [{ "name": "garage LA", "cars": [{ "car": "Ferrari", "color": "Red" }, { "car": "Rolls Royce", "color": "Purple" }, { "car": "Ferrari", "color": "Orange" } ] }, { "name": "garage SF", "cars": [{ "car": "Mercedes", "color": "Blue" }, { "car": "Ferrari", "color": "Red" } ] }, { "name": "garage NY", "cars": [{ "car": "Aston Martin", "color": "Green" }] }];

// 调用函数
updateObject("Pink", [1, "cars", 1, "color"], garages);
console.log(garages[1].cars[1].color); // 输出 "Pink"

方案二:返回新对象(不修改原对象,适合不可变场景)

如果需要保留原对象的初始状态(比如React状态更新场景),我们需要逐层创建新的嵌套结构,避免浅拷贝导致原对象被修改。这里用递归实现不可变更新:

function updateObject(value, path, obj) {
  // 递归函数:逐层创建新的对象/数组
  function traverse(currentPath, currentObj) {
    // 到达路径终点,返回新值
    if (currentPath.length === 0) {
      return value;
    }
    // 拆分当前路径的第一个键和剩余路径
    const [currentKey, ...remainingPath] = currentPath;
    // 创建当前层级的拷贝:数组用slice,对象用展开运算符
    const newLayer = Array.isArray(currentObj) ? [...currentObj] : { ...currentObj };
    // 递归处理下一层级,替换对应位置的值
    newLayer[currentKey] = traverse(remainingPath, currentObj[currentKey]);
    return newLayer;
  }
  return traverse(path, obj);
}

// 测试用例
let garages = [{ "name": "garage LA", "cars": [{ "car": "Ferrari", "color": "Red" }, { "car": "Rolls Royce", "color": "Purple" }, { "car": "Ferrari", "color": "Orange" } ] }, { "name": "garage SF", "cars": [{ "car": "Mercedes", "color": "Blue" }, { "car": "Ferrari", "color": "Red" } ] }, { "name": "garage NY", "cars": [{ "car": "Aston Martin", "color": "Green" }] }];

// 调用函数,获得新对象
const updatedGarages = updateObject("Pink", [1, "cars", 1, "color"], garages);
console.log(updatedGarages[1].cars[1].color); // 输出 "Pink"
console.log(garages[1].cars[1].color); // 输出 "Red"(原对象未被修改)

为什么之前用reduce没生效?

如果之前尝试用reduce做不可变更新,很可能是只遍历到了目标节点,却没有逐层创建新的拷贝结构——单纯的reduce只会沿着引用遍历,不会自动生成新的对象/数组,所以看起来像是浅拷贝没产生实际修改效果。上面的方案二里,我们在每一层都创建了当前结构的拷贝,确保原对象的引用不被修改。

扩展提示

你还可以给函数加一些边界判断,比如路径中的键不存在时,自动创建默认的对象或数组(比如如果路径是[3, "cars", 0],而原对象里没有索引3的车库,可以自动创建一个空车库对象),根据你的业务需求调整即可。

内容的提问来源于stack exchange,提问作者Soerman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 14:52:41