使用reduce处理对象数组时,变量赋值写法导致代码失效的问题求助
使用reduce处理对象数组时,变量赋值写法导致代码失效的问题求助
嗨,我来帮你梳理下问题所在~首先你想用reduce给数组里缺少yearOfDeath的对象补上这个属性,但你的代码里有几个关键问题,先一一拆解:
先看你代码里的基础错误
- reduce的初始值错了:你把初始值设成了
{}(对象),但你想要生成的是数组,应该改成[]才对。 - 每次循环清空累加器:你在回调里写了
accum = [],这会把之前累加的结果全部清空,完全违背了reduce“累加”的核心逻辑,相当于每次循环都重新创建一个空数组,最后肯定得不到正确结果。 - 忘记返回累加器:
reduce的回调函数必须返回当前的累加器,否则下一次循环的accum会变成undefined,整个逻辑直接崩掉。
再解释两种赋值写法的区别
你困惑的两种写法,本质上是完全不同的操作:
第一种:
accum.push(passed = currentYear)
这里的passed = currentYear是一个赋值表达式,它的结果是currentYear这个数字,所以你往accum里push的是一个年份数字,而不是修改后的person对象。而且这个操作只是给变量passed赋值,和原person对象没有任何关系,所以person的yearOfDeath属性依然不存在。第二种:
accum.push(person.yearOfDeath = currentYear)
这个写法里person.yearOfDeath = currentYear确实给person对象添加上了yearOfDeath属性,但赋值表达式的结果还是currentYear这个数字,所以你push到accum里的依然是数字,不是修改后的对象。另外,因为对象是引用类型,这里直接修改了原数组里的person对象,会产生“副作用”(原数据被改动),这通常不是我们想要的。
正确的写法示例
如果你想生成一个新数组,同时不修改原数组的对象(推荐这种无副作用的写法),可以这么写:
const people = [ { name: "Carly", yearOfBirth: 2018 }, { name: "Ray", yearOfBirth: 1962, yearOfDeath: 2011 }, { name: "Jane", yearOfBirth: 1912, yearOfDeath: 1941 }, ]; const newArray = people.reduce((accum, person) => { // 复制原对象,避免修改原数据 const newPerson = { ...person }; // 如果没有yearOfDeath,就补上当前年份 if (!newPerson.yearOfDeath) { newPerson.yearOfDeath = new Date().getFullYear(); } // 将修改后的新对象加入累加器 accum.push(newPerson); // 必须返回累加器,供下一次循环使用 return accum; }, []); // 初始值是数组 console.log(newArray);
如果不在意修改原数组(不推荐,因为会污染原数据),可以简化成:
const newArray = people.reduce((accum, person) => { if (!person.yearOfDeath) { person.yearOfDeath = new Date().getFullYear(); } accum.push(person); return accum; }, []);
这样就能得到你想要的每个对象都带yearOfDeath的新数组啦~
备注:内容来源于stack exchange,提问作者lunarchild
相关产品推荐
相关产品推荐

