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

JavaScript/TypeScript中forEach嵌套map数据覆盖问题及ES6简化实现

问题解答

1. 第一次迭代数据被覆盖的原因

JavaScript里的对象属于引用类型,你代码里的数组b存储的是两个对象的引用。循环过程中:

  • 第一次遍历a的NameOne元素时,修改了b里两个对象的data属性,随后把这两个对象的引用push到c中;
  • 第二次遍历a的NameTwo元素时,依旧直接修改b里那两个原对象的data属性,而c里之前存入的元素和b里的对象是同一个引用,因此之前的NameOne和WeekOne会被新值覆盖。
    最终c里的四个元素其实重复指向b里的两个对象,所以所有data都显示第二次迭代的结果。

2. ES6简便实现方法

核心是每次迭代时创建新对象,避免修改原对象的引用。可以用flatMap结合对象扩展运算符...实现,代码更简洁:

const a = [
  { name: 'NameOne', weekName: 'WeekOne' },
  { name: 'NameTwo', weekName: 'WeekTwo' },
];

const bTemplate = [
  { id: 'Name', type: 'text', data: '' },
  { id: 'Week', type: 'text', data: '' },
];

// 生成期望的c数组
const c = a.flatMap(element => {
  return bTemplate.map(template => {
    // 复制模板对象,根据id赋值对应data
    return {
      ...template,
      data: template.id === 'Name' ? element.name : element.weekName
    };
  });
});

console.log(c);

代码说明:

  • flatMap:遍历a的每个元素,返回的数组会自动展开,避免出现嵌套数组;
  • 扩展运算符...template:复制模板对象的所有属性,创建新对象,不会修改原bTemplate的内容;
  • 三元运算符替代多分支if,简化逻辑。

运行后会得到期望输出:

[
  { id: 'Name', type: 'text', data: 'NameOne' },
  { id: 'Week', type: 'text', data: 'WeekOne' },
  { id: 'Name', type: 'text', data: 'NameTwo' },
  { id: 'Week', type: 'text', data: 'WeekTwo' }
]

内容的提问来源于stack exchange,提问作者R.H

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:01:06