I want to make an array based on two arrays - "ideaList" and "endorsements" declared globally. As ideaList and endorsements are used in other parts of the program I need them to be immutable, and I thought that .map and .filter would keep this immutability.
function prepareIdeaArray(){
var preFilteredIdeas=ideaList
.filter(hasIdeaPassedControl)
.map(obj => {obj.count = endorsements
.filter(x=>x.ideaNumber===obj.ideaNumber)
.reduce((sum, x)=>sum+x.count,0);
obj.like = endorsements
.filter(x=>x.ideaNumber===obj.ideaNumber && x.who===activeUser)
.reduce((sum, x)=>sum+x.count,0)===0?false:true
obj.position = generatePosition(obj.status)
obj.description = obj.description.replace(/\n/g, '<br>')
return obj;});
preFilteredIdeas.sort(compareOn.bind(null,'count',false)).sort(compareOn.bind(null,'position',true))
return preFilteredIdeas;
}
However, when I console.log ideaList after this function has been executed, I remark that objects of the array all have the "count", "like", "position" properties with values, which proves that the array has been mutated.
I tried by using .map only, but same result.
Would you know how I could prevent ideaList to get mutated? Also I would like to avoid to use const, as I declare ideaList globally first, and then assign to it some data in another function.
In JavaScript, only objects and arrays are mutable, not primitive values.
You can freeze (make immutable) an object using the function Object. freeze(obj) . The object passed to the freeze method will become immutable. The freeze() method also returns the same object.
In JavaScript Arrays and Objects are not immutable. Their values can be changed over time. Both are always passed as a reference and the vast majority of available methods mutate data in place.
The original array remains intact if you copy the array with the spread operator and append it to the new one. Doing so supports immutability and prevents unforeseen side-effects.
You're not mutating the array itself but rather the objects that the array contains references to. .map()
creates a copy of the array but the references contained in it points to the exact same objects as the original, which you've mutated by adding properties directly to them.
You need to make copies of these objects too and add the properties to these copies. A neat way to do this is to use object spread in .map()
callback:
.map(({ ...obj }) => {
obj.count = endorsements
.filter(x=>x.ideaNumber===obj.ideaNumber)
...
If your environment doesn't support object spread syntax, clone the object with Object.assign()
:
.map(originalObj => {
const obj = Object.assign({}, originalObj);
obj.count = endorsements
.filter(x=>x.ideaNumber===obj.ideaNumber)
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With