JavaScript对象数组reduce使用异常:id重复缺失问题排查
问题原因与解决方案
问题根源
你遇到的id重复、缺失问题,核心是对象引用赋值导致的修改覆盖:
- 代码里的
const r1 = o并没有创建新对象,只是把原数组中对象o的引用赋值给了r1。 - 在
map遍历o.ids时,两次循环操作的都是同一个对象:第一次把id设为2,第二次又把同一个对象的id改成3。最终map返回的两个元素其实是同一个对象的引用,所以数组里的两个"b"对象都会显示最后一次修改的id:3。
修复方案
解决关键是每次循环都创建新对象,而非直接修改原对象。可以用以下两种方式实现:
方案1:对象扩展运算符(推荐)
const ll = [{name:"a", ids:[1]}, {name:"b", ids:[2,3]}]; const result = ll.reduce((r, o) => { return r.concat(o.ids.map(i => ({ ...o, // 浅拷贝原对象的所有属性 ids: null, // 覆盖原ids属性 id: i // 添加新的id属性 }))); }, []); console.log(result); // 输出: // [{ name: 'a', ids: null, id: 1 },{ name: 'b', ids: null, id: 2 },{ name: 'b', ids: null, id: 3 }]
方案2:Object.assign
const ll = [{name:"a", ids:[1]}, {name:"b", ids:[2,3]}]; const result = ll.reduce((r, o) => { return r.concat(o.ids.map(i => Object.assign({}, o, { ids: null, id: i }))); }, []);
两种方式都会生成原对象的浅拷贝,每次map循环都创建独立的新对象,修改新对象的属性不会互相干扰,就能得到预期结果。
内容的提问来源于stack exchange,提问作者vikrant
相关产品推荐
相关产品推荐

