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

为何使用push方法会覆盖对象中数组的全部内容?

宠物记录管理功能中push数据覆盖原有数组的问题解决

问题情况

在TypeScript开发宠物记录管理功能时,调用updateRecord函数向对象内的数组添加新宠物数据时,数组原有内容被意外覆盖。相关代码及逻辑如下:

enum Gender {
  male = "M",
  female = "F",
}
// pet attributes
interface petAttributes {
  age: number;
  name: string;
  gender: Gender;
}
// pet attributes acc to color
interface petDetails {
  [color: string]: Array<petAttributes>;
}
// details and attributes acc to breed
interface petType {
  [type: string]: petDetails;
}
// final dog record 
let dogRecord: petType = {
  labrador: {
    black: [
      {
        age: 1,
        name: "bhalu",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "lily",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      }
    ],
    yellow: [
      {
        age: 1,
        name: "bhalu",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "lily",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
    ],
    chocolate: [
      {
        age: 1,
        name: "bhalu",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "lily",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
    ],
  },
  shitzu: {
    blackWhite: [
      {
        age: 1,
        name: "bhalu",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "lily",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
    ],
  },
  dalmation: {
    blackWhite: [
      {
        age: 1,
        name: "bhalu",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "lily",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
    ],
  },
  viszla: {
    brown: [
      {
        age: 1,
        name: "bhalu",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "lily",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
    ],
  },
  boxer: {
    brown: [
      {
        age: 1,
        name: "bhalu",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "lily",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
    ],
    mix: [
      {
        age: 1,
        name: "bhalu",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "lily",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
    ],
    white: [
      {
        age: 1,
        name: "bhalu",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "lily",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
      {
        age: 2,
        name: "",
        gender: Gender.female,
      },
    ],
  },
};

const updateRecord = ({
  type,
  breed,
  age,
  name,
  color,
  gender,
}: any) => {
  if (type === allPets.dog) {
    for (const property in dogRecord) {
      if (breed === property) {
        let newPet: petAttributes = {
          age,
          name,
          gender,
        };
        console.log(dogRecord[property][color]);
        dogRecord[property][color].push(newPet);
      } else {
        dogRecord[breed] = {
          [color]: [
            {
              age,
              name,
              gender,
            },
          ],
        };
      }
    }
  }
};
// update record with new dog of existing color
updateRecord({
  type: allPets.dog,
  breed: "labrador",
  color: "black",
  age: 1,
  name: "rio",
  gender: Gender.female,
});

原逻辑意图:updateRecord接收参数后,当类型为狗时,遍历dogRecord属性,匹配到目标breed就push新宠物到对应颜色数组;否则为该breed创建新的颜色数组。但实际执行时push操作会覆盖原有数组内容。

问题原因

核心错误在于遍历dogRecord的循环逻辑:

  • 当遍历到与目标breed不匹配的属性时,else分支会直接覆盖dogRecord[breed]的整个对象。
  • 比如更新labrador的black数组时,遍历到shitzu、dalmation等其他breed时,都会触发else分支,把labrador的原有记录替换成仅包含新宠物的数组,导致之前push的内容被覆盖。

修复后的代码

重构updateRecord函数,去掉不必要的遍历,直接检查目标breed和颜色的存在性:

const updateRecord = ({
  type,
  breed,
  age,
  name,
  color,
  gender,
}: {
  type: typeof allPets.dog;
  breed: string;
  age: number;
  name: string;
  color: string;
  gender: Gender;
}) => {
  if (type === allPets.dog) {
    // 检查breed是否存在
    if (dogRecord[breed]) {
      const breedDetails = dogRecord[breed];
      // 检查color数组是否存在
      if (breedDetails[color]) {
        // 存在则push新宠物
        breedDetails[color].push({ age, name, gender });
      } else {
        // 不存在则创建新数组并添加
        breedDetails[color] = [{ age, name, gender }];
      }
    } else {
      // breed不存在则创建新条目
      dogRecord[breed] = {
        [color]: [{ age, name, gender }],
      };
    }
  }
};

修复要点

  1. 移除了遍历dogRecord的循环,避免多次覆盖目标breed的记录
  2. 先判断目标breed是否存在,再处理对应颜色的数组
  3. 完善了参数类型定义,替代原有的any类型,增强类型安全性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:00:54