I was trying to solve another person's problem on SO using Array.prototype.reduce and ...object destructuring. I don't understand why it works as expected when I'm using Object.assign, but not when using the spread operator.
const str = 'Jack:13,Phil:15,Lucy:12'
const arr = str.split(',')
let reducer = (acc, val) => {
return { ...acc,
...{
[val.split(':')[0]]: Number(val.split(':')[1])
}
}
}
let reducer2 = (acc, val) => {
return Object.assign(acc, {
[val.split(':')[0]]: Number(val.split(':')[1])
})
}
let obj = {
Jody: 29
}
let obj2 = {
Julie: 28
}
arr.reduce(reducer, obj)
arr.reduce(reducer2, obj2)
console.log(obj)
/* output:
{
"Jody": 29
}
*/
console.log(obj2)
/* output:
{
"Julie": 28,
"Jack": 13,
"Phil": 15,
"Lucy": 12
}
*/
Array
reduceis often used to return a new value. Even if it mutates an accumulator, it's safe to assume that it can return a new value.arr.reduce(reducer, obj)relies on thatobjis mutated.reducer2mutates original object indeed, this is the reason why it works. But this contradicts withreducerwhich keeps an accumulator immutable.It should be: